using Flurl.Http;
using NPOI.SS.Formula.Functions;
using Pay.Core;
using Pay.Data;
using Pay.DTO;
using Pay.IService;
using Pay.Service.Cache;
using Pay.TO;
using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Data.Entity.SqlServer;
using System.Linq;
using System.Net.Http;
using System.Text.RegularExpressions;
using System.Threading.Tasks;

namespace Pay.Service
{
    public class MerchantService : ServiceBase, IMerchantService, IDisposable
    {
        private IUnitOfWork _iUnitOfWork;
        private IPaymentService _iPaymentService;
        private IRoleService _iroleService;
        private ISettingService _settingService;
        private IInviteHorsePowerSettingService _iInviteHorsePowerSettingService;
        //private ISoupTaskService _iSoupTaskService;
        private HxDataSign _hxDataSign;
        public MerchantService(IUnitOfWork iUnitOfWork, IPaymentService iPaymentService, IRoleService roleService, ISettingService settingService,
                               IInviteHorsePowerSettingService inviteHorsePowerSettingService)
             : base(iUnitOfWork)
        {
            _iUnitOfWork = iUnitOfWork;
            _iPaymentService = iPaymentService;
            _iroleService = roleService;
            _settingService = settingService;
            _iInviteHorsePowerSettingService = inviteHorsePowerSettingService;
            _hxDataSign = new HxDataSign();
        }

        /// <summary>
        /// 根据域名查找对象
        /// </summary>
        /// <param name="domain"></param>
        /// <returns></returns>
        public merchant_dto GetMerchantByDomain(string domain)
        {
            return context.Merchants.Where(c => c.Domain == domain).FromCacheFirstOrDefault<Merchant, merchant_dto>();
        }

        public PagedResult<merchant_info> GetMerchant(MerchantQuery query)
        {
            var filter = PredicateBuilder.True<Merchant>();
            var start_time = query.start_time.ToUnix();
            if (query.start_time.HasValue && query.end_time.HasValue)
            {
                var end_time = query.end_time.Value.AddDays(1).ToUnix();
                filter = filter.And(c => c.CreateTime >= start_time && c.CreateTime <= end_time);
            }
            else if (query.start_time.HasValue && !query.end_time.HasValue)
                filter = filter.And(c => c.CreateTime >= start_time);
            else if (!query.start_time.HasValue && query.end_time.HasValue)
            {
                var end_time = query.end_time.Value.AddDays(1).ToUnix();
                filter = filter.And(c => c.CreateTime <= end_time);
            }
            if (query.certify > 0)
                filter = filter.And(c => c.IsCertify == query.certify);
            if (query.usertype > 0)
                filter = filter.And(c => c.UserType == query.usertype);
            if (query.parent_id > 0)
                filter = filter.And(c => c.ParentId == query.parent_id);
            if (query.oem_id > 0)
                filter = filter.And(c => c.OemId == query.oem_id);
            if (!string.IsNullOrEmpty(query.nick))
                filter = filter.And(c => c.Name.Contains(query.nick));
            if (!string.IsNullOrEmpty(query.mobile))
                filter = filter.And(c => query.mobile == c.Mobile);
            if (!string.IsNullOrEmpty(query.merchant_no))
                filter = filter.And(c => query.merchant_no == c.MerchantNo);
            if (query.disabled.HasValue)
                filter = filter.And(c => c.Disabled == query.disabled.Value);
            if (query.is_oem.HasValue)
                filter = filter.And(c => c.IsOEM == query.is_oem.Value);
            if (query.is_platform.HasValue)
                filter = filter.And(c => c.IsPlatform == query.is_platform.Value);
            if (query.is_supplier.HasValue)
                filter = filter.And(c => c.IsSupplier == query.is_supplier.Value);
            if (query.auth_status.HasValue)
                filter = filter.And(c => c.AuthStatus == query.auth_status.Value);
            if (query.open_wx.HasValue)
            {
                string open_wx = "%\"open_wx\":" + (int)query.open_wx.Value + "%";
                filter = filter.And(c => SqlFunctions.PatIndex(open_wx, c.Setting) > 0);
            }
            var result = context.Merchants.FromCachePaged<Merchant, merchant_info>(query.page, query.size, filter, orderBy => orderBy.OrderByDescending(c => c.Id));
            return result;
        }

        public merchant_info GetMerchant(long id)
        {
            var result = context.Merchants.Where(c => c.Id == id).FromCacheFirstOrDefault<Merchant, merchant_info>();
            result.payments = GetPayments(id);
            result.registers = GetRegisters(id);
            if (result.parent_id > 0)
                result.parent_no = Get(result.parent_id).merchant_no;
            return result;
        }

        public long GetGradeId(string grade_no, string merchant_no)
        {
            var grade = context.Grades.FirstOrDefault(c => c.GradeNo == grade_no && c.MerchantNo == merchant_no);
            return (grade == null ? 0 : grade.Id);
        }

        public List<merchant_dto> GetOems()
        {
            var dto = context.Merchants.Where(c => c.IsOEM).OrderByDescending(c => c.Id).FromCache<Merchant, merchant_dto>();
            return dto;
        }

        public merchant_dto Get(long id)
        {
            return context.Merchants.Where(c => c.Id == id).FromCacheFirstOrDefault<Merchant, merchant_dto>("Merchant" + id);
        }

        /// <summary>
        /// 验证用户密码
        /// </summary>
        /// <param name="userId"></param>
        /// <param name="password"></param>
        /// <returns></returns>
        public bool ValidUserPassword(long userId, string password)
        {
            var user = context.Merchants.Where(o => o.Id == userId).FirstOrDefault();
            if (user != null && user.Password == WebHelper.GetPasswrodWithTwiceEncode(password, user.PasswordSalt))
                return true;
            return false;
        }

        public authinfo_dto GetAuth(long merchantId)
        {
            var result = ("AuthInfo" + merchantId)
                    .FromCacheLinq(() =>
                    {
                        var auth = context.AuthInfos.Where(c => c.MerchantId == merchantId)
                                .OrderByDescending(c => c.Id)
                                .FirstOrDefault();
                        if (auth != null)
                            return auth.ToDtoObject<authinfo_dto>();
                        return null;
                    }, "Merchant" + merchantId);
            return result;
            //return context.AuthInfos.Where(c => c.MerchantId == merchantId && c.Status == CertifyStatus.Auth).FromCacheFirstOrDefault<AuthInfo, authinfo_dto>("Merchant" + merchantId);
        }

        public authinfo_dto GetAuthById(long id)
        {
            return context.AuthInfos.FindById(id).ToDtoObject<authinfo_dto>();
        }

        public merchant_dto Get(string merchant_no)
        {
            return context.Merchants.Where(c => c.MerchantNo == merchant_no).FromCacheFirstOrDefault<Merchant, merchant_dto>("Merchant" + merchant_no);
        }

        public Data.BankCode GetBankCode(string accountNo, string cardType)
        {
            return context.BankCodes.Where(c => c.CardType == cardType && c.AccountNo == accountNo).FirstOrDefault();
        }

        public Merchant GetMerchant(string bindNo)
        {
            return context.Merchants.Where(c => c.MerchantNo == bindNo).FirstOrDefault();
        }

        /// <summary>
        /// 查询用户的所有上级（N），默认包括本身
        /// </summary>
        /// <param name="id"></param>
        /// <param name="contains">是否包括本身</param>
        /// <returns></returns>
        public List<merchant_dto> GetParents(long id, bool contains = true)
        {
            var query = from a in context.Merchants
                        from b in context.MemberPaths
                        where a.Id == b.ParentId && b.MemberId == id
                        orderby a.Depth descending
                        select a;

            var result = query.FromCache<Merchant, merchant_dto>();
            if (!contains) result.RemoveAll(c => c.id == id);
            return result;
        }

        /// <summary>
        /// 查询所有下级，默认不包括本身
        /// </summary>
        /// <returns>The childs.</returns>
        /// <param name="id">Identifier.</param>
        public List<merchant_dto> GetChilds(long id, bool contains = false)
        {
            var query = from a in context.Merchants
                        from b in context.MemberPaths
                        where a.Id == b.MemberId && b.ParentId == id
                        orderby a.Depth ascending
                        select a;
            var result = query.FromCache<Merchant, merchant_dto>();
            if (!contains) result.RemoveAll(c => c.id == id);
            return result;
        }

        /// <summary>
        /// 通过手机和密码注册
        /// </summary>
        /// <param name="register">注册请求信息</param>
        /// <returns></returns>
        public merchant_dto Register(register_model register)
        {
            if (string.IsNullOrEmpty(register.mobile))
                throw new ServerErrorException("手机号码不能是空的");
            if (string.IsNullOrEmpty(register.password))
                throw new ServerErrorException("密码不能是空的");
            if (string.IsNullOrEmpty(register.re_password))
                throw new ServerErrorException("确认密码不能是空的");
            if (register.password != register.re_password)
                throw new ServerErrorException("密码和确认密码不一致");
            if (!string.IsNullOrEmpty(register.parent_no) && register.parent_no == register.mobile)
                throw new ServerErrorException("邀请人不能是自己");
            if (!string.IsNullOrEmpty(register.code))
            {
                _settingService.ValidCode(register.mobile, register.code, "register");
            }

            var model = new Merchant();
            model.MobileCode = string.IsNullOrEmpty(register.mobile_code) ? "86" : register.mobile_code;
            model.Mobile = register.mobile;
            if (!string.IsNullOrEmpty(register.name))
                model.Name = register.name;
            string salt = Guid.NewGuid().ToString("N").Substring(12);
            model.PasswordSalt = salt;
            model.Password = WebHelper.GetPasswrodWithTwiceEncode(register.password, salt);
            model.CreateTime = model.LoginTime = DateTime.Now.ToUnix();
            model.IsSupplier = register.is_supplier;
            model.MerchantNo = DateTime.Now.ToUnix() + DtoHelper.RandCode(4);
            if (!string.IsNullOrEmpty(register.open_id))
                model.OpenId = register.open_id;
            else
                model.OpenId = model.MerchantNo;
            model.Setting = new merchant_setting().ToJson();
            model.AuthStatus = AuthStatusEnum.None;
            if (!string.IsNullOrEmpty(register.oem_no))
            {
                var oem = Get(register.oem_no);
                model.OemId = oem.id;
                if (context.Merchants.Exist(c => c.Mobile == register.mobile && c.OemId == model.OemId))
                    throw new ServerErrorException("商户已经存在不可以注册");
            }
            else
            {
                if (context.Merchants.Exist(c => c.Mobile == register.mobile))
                    throw new ServerErrorException("商户已经存在不可以注册");
            }

            if (register.grade_id.HasValue)
                model.GradeId = register.grade_id;
            model.IsOEM = register.is_oem;
            if (register.user_type == UserType.None)
            {
                if (register.is_oem == true)
                    model.UserType = UserType.oem;
                model.IsPlatform = register.is_platform;
                if (!register.is_supplier && !register.is_oem && !register.is_platform)
                    model.UserType = UserType.distributor;
                if (register.is_supplier)
                    model.UserType = UserType.supplier;
            }
            else model.UserType = register.user_type;
            merchant_dto parent = null;
            int depth = 1;
            if (!string.IsNullOrEmpty(register.parent_no))
            {
                parent = Get(register.parent_no);
                model.ParentId = parent.id;
            };

            var trans = context.Database.BeginTransaction();
            try
            {
                IEnumerable<merchant_dto> parents = new List<merchant_dto>();
                if (model.ParentId > 0)
                {
                    parents = GetParents(model.ParentId);
                    depth = parents.Count() + 1;
                }
                model.Depth = depth;
                model.Name = model.Name == null ? model.Mobile : model.Name;
                context.Merchants.Add(model);
                int result = _iUnitOfWork.Commit();
                var userid = model.Id;
                //开个店
                if (register.is_supplier)
                    context.ShopInfo.Add(new ShopInfo { ShopName = model.Name + "节点商城", CreateTime = model.CreateTime, CustomerTel = model.Mobile, Id = userid, Rate = 0.5M });
                //用户关系
                List<MemberPath> memberPaths = new List<MemberPath>();
                //新用户id也加入
                memberPaths.Add(new MemberPath { MemberId = userid, ParentId = userid });
                //增加上下级关系
                foreach (var item in parents)
                    memberPaths.Add(new MemberPath { MemberId = userid, ParentId = item.id });
                context.MemberPaths.AddRange(memberPaths);

                if (!string.IsNullOrEmpty(register.code))
                {
                    _settingService.RemoveCode(register.mobile, "register");
                }
                if (register.role_id > 0)
                {
                    context.Manages.Add(new Manage
                    {
                        LoginTime = model.LoginTime,
                        Mobile = register.mobile,
                        MerchantId = userid,
                        Nick = string.IsNullOrEmpty(register.name) ? register.mobile : register.name,
                        RoleId = register.role_id,
                        Password = model.Password,
                        PasswordSalt = model.PasswordSalt
                    });
                }
                _iUnitOfWork.Commit("Manage");
                trans.Commit();
                return Get(model.Id);
            }
            catch (Exception ex)
            {
                trans.Rollback();
                var log = IocHelper.Get<ILogHelper>("data_error");
                log.Error(model.Mobile + "注册失败");
                log.Error(ex.Message, ex);
                return null;
            }
        }

        /// <summary>
        /// 通过手机和密码登录
        /// </summary>
        /// <param name="mobile"></param>
        /// <param name="password"></param>
        /// <returns></returns>
        public merchant_dto Login(string mobile, string password, string oem_no)
        {
            if (string.IsNullOrEmpty(mobile))
                throw new ServerErrorException("手机号码没有填写");
            if (string.IsNullOrEmpty(password))
                throw new ServerErrorException("密码没有填写");
            var oemer = Get(oem_no);
            var model = context.Merchants.FirstOrDefault(c => c.Mobile == mobile && c.OemId == oemer.id);
            if (model == null)
                throw new ServerErrorException("用户不存在");
            else if (model != null && model.Password != WebHelper.GetPasswrodWithTwiceEncode(password, model.PasswordSalt))
                throw new ServerErrorException("密码不正确");
            if (model.Disabled)
            {
                string service_phone = _settingService.GetTokenSetting().app.service_phone;
                throw new ServerErrorException(string.Format("您的账号已冻结请拨打{0}联系客服解冻", service_phone));
            }
            model.LoginTime = DateTime.Now.ToUnix();

            _iUnitOfWork.Commit("Merchant" + model.Id);

            var user = Get(model.Id);

            return user;
        }

        /// <summary>
        /// 用手机登录，现于TOKEN注册到戈仑埠
        /// </summary>
        /// <param name="mobile"></param>
        /// <param name="oem_no"></param>
        /// <returns></returns>
        public merchant_dto LoginByMobile(string mobile, string oem_no)
        {
            var oemer = Get(oem_no);
            return context.Merchants.Where(c => c.Mobile == mobile && c.OemId == oemer.id).FromCacheFirstOrDefault<Merchant, merchant_dto>();
        }

        /// <summary>
        /// 创建Token测试（运营）用户
        /// </summary>
        public int CreateTokenTestUser(string mobileSuffix)
        {
            if (mobileSuffix.Length != 4)
                throw new ServerErrorException("手机号后缀只能为4位");
            if (!Regex.IsMatch(mobileSuffix, @"^[0-9]*[1-9][0-9]*$"))
                throw new ServerErrorException("手机号后缀只能为4位纯数字");
            string mobile = t_RequestMethod.TestMobiePrefix + mobileSuffix;
            int result = 0;
            string oemMerchantNo = t_RequestMethod.merchant_no;
            var oem = context.Merchants.FirstOrDefault(c => c.MerchantNo == oemMerchantNo);
            //已注册
            var model = context.Merchants.FirstOrDefault(c => c.Mobile == mobile && c.IsOEM == false && c.OemId == oem.Id);
            if (model != null)
                throw new ServerErrorException("手机号已创建");

            DateTime dt = DateTime.Now;
            model = new Merchant();
            model.Mobile = mobile;
            model.OpenId = model.MerchantNo = DateTime.Now.ToUnix() + DtoHelper.RandCode(4);
            model.CreateTime = model.LoginTime = DateTime.Now.ToUnix();
            model.AuthStatus = AuthStatusEnum.None;
            model.OemId = oem.Id;
            model.Name = mobile;
            model.ParentId = 0;
            model.Depth = 1;
            model.Setting = new merchant_setting().ToJson();
            model.PublicKey = model.Photo = model.Remark = model.Password = model.PasswordSalt = string.Empty;
            model.UserType = UserType.user;
            model.IsOEM = model.IsPlatform = model.IsSupplier = model.TradeOutPay = false;
            RedRecord red = new RedRecord();
            red.CreateTime = red.NextProductionTime = red.RegisterTime = dt.ToUnix();
            var token = _settingService.GetTokenSetting().token;
            int dayTotalRed = token.day_total_red_drill;
            int merchantTotalHorsePower = token.total_horse_power;
            //初始用户30
            decimal redNum = (decimal)dayTotalRed * 30 / merchantTotalHorsePower;
            red.DayRedDrill = RedMakeHelp.GetTimeAndRed(dt, redNum).ToJson();
            red.InvitationCodeNum = 0;
            red.IsFinish = false;
            red.TotalHorsePower = 30;

            var trans = context.Database.BeginTransaction();
            try
            {
                context.Merchants.Add(model);
                int r = _iUnitOfWork.Commit();
                red.MerchantId = model.Id;
                red.InvitationCode = InvitationCodeHelp.toSerialCode(model.Id);
                context.RedRecord.Add(red);
                //增加关系
                context.MemberPaths.Add(new MemberPath { MemberId = model.Id, ParentId = model.Id });
                result = _iUnitOfWork.Commit();
                if (r > 0 && result > 0)
                {
                    trans.Commit();
                }
            }
            catch (Exception ex)
            {
                trans.Rollback();
                var log = IocHelper.Get<ILogHelper>("data_error");
                log.Error(model.Mobile + "创建测试用户失败");
                log.Error(ex.Message, ex);
            }

            return result;

        }

        /// <summary>
        /// token注册--v05-v0.7版本的注册交流
        /// </summary>
        /// <param name="register_model"></param>
        /// <returns></returns>
        public async Task<merchant_dto> TokenRegisterAsync(token_register_model register_model)
        {
            _settingService.ValidCode(register_model.mobile, register_model.code, "token_register");
            if (register_model.mobile_code == "886") throw new ServerErrorException("台湾地区暂未开放注册");
            string oemMerchantNo = t_RequestMethod.merchant_no;
            var oem = context.Merchants.FirstOrDefault(c => c.MerchantNo == oemMerchantNo);
            var model = context.Merchants.FirstOrDefault(c => c.Mobile == register_model.mobile && c.IsOEM == false && c.OemId == oem.Id);
            if (model != null)
                throw new ServerErrorException("用户已经存在不可以注册");
            if (!string.IsNullOrEmpty(register_model.invitation_code) && register_model.invitation_code.Contains("0"))
            {//用户输入数字0替换成字母O，防止用户输错
                register_model.invitation_code = register_model.invitation_code.Replace("0", "O");
            }
            var parentRed = context.RedRecord.Where(s => s.InvitationCode == register_model.invitation_code).FirstOrDefault();
            if (parentRed == null) throw new ServerErrorException("邀请码不正确");

            if (register_model.mobile.Contains(t_RequestMethod.TestMobiePrefix)) throw new ServerErrorException("手机号不正确");
            var parent = context.Merchants.FindById(parentRed.MerchantId);
            DateTime dt = DateTime.Now;
            var udt = dt.ToUnix();
            //用户
            model = new Merchant();
            model.Mobile = register_model.mobile;
            model.OpenId = model.MerchantNo = udt + DtoHelper.RandCode(4);
            model.CreateTime = model.LoginTime = udt;
            model.AuthStatus = AuthStatusEnum.None;
            model.OemId = oem.Id;
            model.Name = register_model.mobile;
            model.ParentId = parent.Id;
            model.Setting = new merchant_setting().ToJson();
            model.PublicKey = model.Photo = model.Remark = string.Empty;
            string salt = Guid.NewGuid().ToString("N").Substring(12);
            model.PasswordSalt = salt;
            model.Password = WebHelper.GetPasswrodWithTwiceEncode(register_model.password, salt);
            model.UserType = UserType.user;
            model.IsOEM = model.IsPlatform = model.IsSupplier = model.TradeOutPay = false;
            model.MobileCode = register_model.mobile_code;
            var auth = context.AuthInfos.Where(s => s.Status == CertifyStatus.Auth && s.PayChannel == PayChannel.None);
            if (auth.FirstOrDefault(s => s.IdCard == register_model.card_no) != null) throw new ServerErrorException("该身份证已被实名认证");
            int flag = 0;
            string msg = string.Empty;
            if (register_model.mobile_code == "86")
            {
                var content = new Dictionary<string, string>();
                content.Add("username", "zs_20180528");
                content.Add("apikey", "2c1eab15e9df2499c03f52fad60bde01");
                content.Add("name", register_model.user_name);
                content.Add("id", register_model.card_no);
                var formUrlContent = new FormUrlEncodedContent(content);
#if DEBUG
                var result = await Task.FromResult(new bank_api_result { guid = "test", MESSAGE = "成功啦", RESULT = "1" });
#else
                var result = await t_RequestMethod.bankapi.PostAsync(formUrlContent).ReceiveJson<bank_api_result>();
#endif
                if (result != null)
                {
                    msg = result.MESSAGE + "***" + result.RESULT + "***" + result.guid;
                    if (result.RESULT != "1")
                    {
                        var log = IocHelper.Get<ILogHelper>("info");
                        log.Info(register_model.mobile + "***" + register_model.card_no + "***" + register_model.user_name + "***" + result.MESSAGE + "***" + result.RESULT + "***" + result.guid);
                        throw new ServerErrorException("实名认证失败,请输入正确的身份证和姓名");
                    }

                    flag = 1;
                }
                else
                {
                    throw new ServerErrorException("实名认证失败");

                }
            }
            else
            {
                Regex reg = new Regex(@"^[a-zA-Z][0-9]{9}$");
                if (!reg.IsMatch(register_model.card_no)) throw new ServerErrorException("身份证号码不正确");
                msg = "台湾";
                flag = 1;
            }
            AuthInfo authinfo = new AuthInfo
            {
                OrderNo = string.Empty,
                PayChannel = PayChannel.None,
                MerchantId = model.Id,
                AccountNo = string.Empty,
                AccountName = register_model.user_name,
                Mobile = register_model.mobile,
                IdCard = register_model.card_no,
                Type = 3,
                Amount = 0,
                CreateTime = DateTime.Now.ToUnix(),
                Remark = msg,
                Status = flag == 1 ? CertifyStatus.Auth : CertifyStatus.Fail
            };
            //红钻
            RedRecord redRecord = new RedRecord();
            redRecord.CreateTime = redRecord.NextProductionTime = redRecord.RegisterTime = dt.ToUnix();
            var token = _settingService.GetTokenSetting().token;
            int dayTotalRed = token.day_total_red_drill;
            int merchantTotalHorsePower = token.total_horse_power;
            //初始用户30
            decimal redNum = (decimal)dayTotalRed * 30 / merchantTotalHorsePower;
            redRecord.DayRedDrill = RedMakeHelp.GetTimeAndRed(dt, redNum).ToJson();
            redRecord.InvitationCodeNum = 0;
            redRecord.IsFinish = false;
            redRecord.TotalHorsePower = 30;
            var soup = context.SoupTask.FirstOrDefault(s => s.Type == ETaskType.InviteRegister);
            soup.GetNum += 1;
            UserSoupValueHis soupValue = new UserSoupValueHis();
            soupValue.ItemId = 0;
            var overInviteRegisterSoupValue = 1;
            var inviteHorsePowerSetting = _iInviteHorsePowerSettingService.GetInviteHorsePowerSettingByTime(dt);
            if (inviteHorsePowerSetting != null)
            {
                overInviteRegisterSoupValue = inviteHorsePowerSetting.horse_power;
            }
            soupValue.SoupValue = parentRed.InvitationCodeNum < 10 ? soup.SoupValue.GetValueOrDefault(10) : overInviteRegisterSoupValue;
            soupValue.TaskType = ETaskType.InviteRegister;
            soupValue.UserId = parentRed.MerchantId;
            soupValue.CreateTime = udt;
            context.UserSoupValueHis.Add(soupValue);
            //红钻
            parentRed.TotalHorsePower = parentRed.TotalHorsePower + (parentRed.InvitationCodeNum < 10 ? soup.SoupValue.GetValueOrDefault(10) : overInviteRegisterSoupValue);
            parentRed.InvitationCodeNum = parentRed.InvitationCodeNum + 1;
            //用户邀请记录
            UserInvitationHis userInvitationHis = new UserInvitationHis();
            userInvitationHis.InvitationCode = register_model.invitation_code;
            userInvitationHis.InvitedUserId = parent.Id;
            userInvitationHis.CreateTime = DateTime.Now;

            var trans = context.Database.BeginTransaction();
            try
            {
                IEnumerable<merchant_dto> parents = new List<merchant_dto>();
                int depth = 1;
                if (model.ParentId > 0)
                {
                    parents = GetParents(model.ParentId);
                    depth = parents.Count() + 1;
                }
                model.Depth = depth;
                context.Merchants.Add(model);
                int r = _iUnitOfWork.Commit();
                //增加关系
                List<MemberPath> memberPaths = new List<MemberPath>();
                //新用户id也加入
                memberPaths.Add(new MemberPath { MemberId = model.Id, ParentId = model.Id });
                //增加上下级关系
                foreach (var item in parents)
                    memberPaths.Add(new MemberPath { MemberId = model.Id, ParentId = item.id });
                context.MemberPaths.AddRange(memberPaths);

                //加钻记录
                redRecord.MerchantId = model.Id;
                redRecord.InvitationCode = InvitationCodeHelp.toSerialCode(model.Id);
                context.RedRecord.Add(redRecord);

                //实名记录
                authinfo.MerchantId = model.Id;
                context.AuthInfos.Add(authinfo);

                //邀请记录
                userInvitationHis.UserId = model.Id;
                context.UserInvitationHis.Add(userInvitationHis);
                int r1 = _iUnitOfWork.Commit();
                if (r > 0 && r1 > 0)
                {
                    trans.Commit();
                    _settingService.RemoveCode(register_model.mobile, "token_register");
                }
            }
            catch (Exception ex)
            {
                trans.Rollback();
                var log = IocHelper.Get<ILogHelper>("data_error");
                log.Error(model.Mobile + "注册失败");
                log.Error(ex.Message, ex);
            }
            return Get(model.Id);
        }

        /// <summary>
        /// 新注册流程，直接手机号+邀请码；实名在任务完成 
        /// </summary>
        /// <param name="register_model"></param>
        /// <returns></returns>
        public merchant_dto TokenRegister2Async(token_register_model register_model)
        {
            _settingService.ValidCode(register_model.mobile, register_model.code, "token_register");
            string oemMerchantNo = t_RequestMethod.merchant_no;
            var oem = context.Merchants.FirstOrDefault(c => c.MerchantNo == oemMerchantNo);
            var model = context.Merchants.FirstOrDefault(c => c.Mobile == register_model.mobile && c.IsOEM == false && c.OemId == oem.Id);
            if (model != null)
                throw new ServerErrorException("用户已经存在不可以注册");
            if (!string.IsNullOrEmpty(register_model.invitation_code) && register_model.invitation_code.Contains("0"))
            {//用户输入数字0替换成字母O，防止用户输错
                register_model.invitation_code = register_model.invitation_code.Replace("0", "O");
            }
            var parentRed = context.RedRecord.Where(s => s.InvitationCode == register_model.invitation_code).FirstOrDefault();
            if (parentRed == null) throw new ServerErrorException("邀请码不正确");

            if (register_model.mobile.Contains(t_RequestMethod.TestMobiePrefix)) throw new ServerErrorException("手机号不正确");
            var parent = context.Merchants.FindById(parentRed.MerchantId);
            DateTime dt = DateTime.Now;
            var udt = dt.ToUnix();
            //用户
            model = new Merchant();
            model.Mobile = register_model.mobile;
            model.OpenId = model.MerchantNo = udt + DtoHelper.RandCode(4);
            model.CreateTime = model.LoginTime = udt;
            model.AuthStatus = AuthStatusEnum.None;
            model.OemId = oem.Id;
            model.Name = register_model.mobile;
            model.ParentId = parent.Id;
            model.Setting = new merchant_setting().ToJson();
            model.PublicKey = model.Photo = model.Remark = string.Empty;
            string salt = Guid.NewGuid().ToString("N").Substring(12);
            model.PasswordSalt = salt;
            model.Password = WebHelper.GetPasswrodWithTwiceEncode(register_model.password, salt);
            model.UserType = UserType.user;
            model.IsOEM = model.IsPlatform = model.IsSupplier = model.TradeOutPay = false;
            model.MobileCode = register_model.mobile_code;
            //红钻
            RedRecord redRecord = new RedRecord();
            redRecord.CreateTime = redRecord.NextProductionTime = redRecord.RegisterTime = dt.ToUnix();
            redRecord.DayRedDrill = "{}";
            var token = _settingService.GetTokenSetting().token;
            int dayTotalRed = token.day_total_red_drill;
            int merchantTotalHorsePower = token.total_horse_power;
            //用户邀请记录
            UserInvitationHis userInvitationHis = new UserInvitationHis();
            userInvitationHis.InvitationCode = register_model.invitation_code;
            userInvitationHis.InvitedUserId = parent.Id;
            userInvitationHis.CreateTime = DateTime.Now;

            var trans = context.Database.BeginTransaction();
            try
            {
                IEnumerable<merchant_dto> parents = new List<merchant_dto>();
                int depth = 1;
                if (model.ParentId > 0)
                {
                    parents = GetParents(model.ParentId);
                    depth = parents.Count() + 1;
                }
                model.Depth = depth;
                context.Merchants.Add(model);
                int r = _iUnitOfWork.Commit();
                //增加关系
                List<MemberPath> memberPaths = new List<MemberPath>();
                //新用户id也加入
                memberPaths.Add(new MemberPath { MemberId = model.Id, ParentId = model.Id });
                //增加上下级关系
                foreach (var item in parents)
                    memberPaths.Add(new MemberPath { MemberId = model.Id, ParentId = item.id });
                context.MemberPaths.AddRange(memberPaths);

                //加钻记录
                redRecord.MerchantId = model.Id;
                redRecord.InvitationCode = InvitationCodeHelp.toSerialCode(model.Id);
                context.RedRecord.Add(redRecord);

                //邀请记录
                userInvitationHis.UserId = model.Id;
                context.UserInvitationHis.Add(userInvitationHis);
                int r1 = _iUnitOfWork.Commit();
                if (r > 0 && r1 > 0)
                {
                    trans.Commit();
                    _settingService.RemoveCode(register_model.mobile, "token_register");
                }
            }
            catch (Exception ex)
            {
                trans.Rollback();
                var log = IocHelper.Get<ILogHelper>("data_error");
                log.Error(model.Mobile + "注册失败");
                log.Error(ex.Message, ex);
            }
            return Get(model.Id);
        }

        /// <summary>
        /// token 实名认证--任务
        /// </summary>
        /// <returns></returns>
        public async Task<authinfo_req> VerificationCard(token_auth_model model, long merchantId)
        {
            model.type = model.type == 0 ? 1 : model.type;
            var dt = DateTime.Now;
            var unixdt = dt.ToUnix();
            var merchant = context.Merchants.FirstOrDefault(s => s.Id == merchantId);
            //var authinfo = context.AuthInfos.FirstOrDefault(s => s.MerchantId == merchantId);
            var authinfo = context.AuthInfos.Where(c => c.MerchantId == merchantId)
                                .OrderByDescending(c => c.Id)
                                .FirstOrDefault();
            var no_auth = authinfo == null;
            if (no_auth)
            {
                authinfo = new AuthInfo
                {
                    MerchantId = merchantId,
                    AccountName = model.user_name,
                    AccountNo = string.Empty,
                    BankName = string.Empty,
                    OrderNo = string.Empty,
                    CreateTime = unixdt,
                    IdCard = model.card_no,
                    Mobile = merchant.Mobile,
                    Type = 4,
                    CertificateType = model.type
                };
            }
            else
            {
                if (authinfo.Amount >= 3) throw new ServerErrorException("实名最多只允许提交三次，请联系客服处理");
                authinfo.IdCard = model.card_no;
                authinfo.AccountName = model.user_name;
                authinfo.CertificateType = model.type;
                authinfo.CardImg = model.card_img;
            }
            //只能提交三次，多出不行
            authinfo.Amount += 1;
            if (authinfo.Status == CertifyStatus.Auth) throw new ServerErrorException("您已实名认证");
            long oem_id = merchant.OemId.Value;
            var hasAuth = context.AuthInfos.Any(s => s.MerchantId != merchantId && s.IdCard == model.card_no && s.Merchant.OemId == oem_id);
            if (hasAuth) throw new ServerErrorException("该身份证已被实名认证");
            int flag = 0;
            if (model.type == 1)
            {
                var content = new Dictionary<string, string>();
                content.Add("username", "zs_20180528");
                content.Add("apikey", "2c1eab15e9df2499c03f52fad60bde01");
                content.Add("name", model.user_name);
                content.Add("id", model.card_no);
                //content.Add("mobile", merchant.Mobile);
                var formUrlContent = new FormUrlEncodedContent(content);
#if DEBUG
                var result = await Task.FromResult(new bank_api_result { guid = "test", MESSAGE = "debug成功了", RESULT = "1" });
#else
                 var result = await Task.FromResult(new bank_api_result { guid = "release", MESSAGE = "实名成功了", RESULT = "1" });
               // var result = await t_RequestMethod.bankapi.PostAsync(formUrlContent).ReceiveJson<bank_api_result>();
                //var result = await "https://apiapi.top/v1/IdNameMobile".PostAsync(formUrlContent).ReceiveJson<bank_api_result>();
#endif
                if (result != null)
                {
                    var tags = new List<string> { "Merchant" + merchantId };
                    authinfo.Status = result.RESULT == "1" ? CertifyStatus.Auth : CertifyStatus.Fail;
                    authinfo.Remark = result.MESSAGE + "***" + result.RESULT + "***" + result.guid;
                    if (authinfo.Status == CertifyStatus.Auth)
                    {
                        AuthInfoApprovedHandle(merchantId, dt, unixdt, merchant, tags);
                    }
                    //对以前没有实名的防错
                    if (no_auth) context.AuthInfos.Add(authinfo);

                    flag = _iUnitOfWork.Commit(tags.ToArray());
                    if (result.RESULT != "1") throw new ServerErrorException("实名认证失败,请输入正确的身份证和姓名");
                    if (flag > 0)
                        return authinfo.ToDtoObject<authinfo_req>();
                    return null;
                }
                else
                {
                    throw new ServerErrorException("实名认证失败");
                }
            }
            else
            {
                authinfo.Type = 5;
                authinfo.Remark = "";
                authinfo.Status = CertifyStatus.UnConfirm;
                authinfo.CardImg = model.card_img;
                authinfo.CertificateType = model.type;
                //对以前没有实名的防错
                if (no_auth) context.AuthInfos.Add(authinfo);
                flag = _iUnitOfWork.Commit();
                if (flag > 0)
                    return authinfo.ToDtoObject<authinfo_req>();
                return null;
            }
        }

        /// <summary>
        /// 实名认证审核通过处理（初始化用户马力、红钻、完成实名任务）
        /// </summary>
        /// <param name="merchantId"></param>
        /// <param name="dt"></param>
        /// <param name="unixdt"></param>
        /// <param name="merchant"></param>
        /// <param name="tags"></param>
        private void AuthInfoApprovedHandle(long merchantId, DateTime dt, long unixdt, Merchant merchant, List<string> tags)
        {
            //红钻
            RedRecord redRecord = context.RedRecord.FirstOrDefault(c => c.MerchantId == merchantId);
            var token = _settingService.GetTokenSetting().token;
            int dayTotalRed = token.day_total_red_drill;
            int merchantTotalHorsePower = token.total_horse_power;
            //初始用户30
            var regSoup = context.SoupTask.FirstOrDefault(s => s.Type == ETaskType.Auth);
            regSoup.GetNum += 1;
            int regSoupValue = regSoup.SoupValue ?? 30;
            decimal redNum = (decimal)dayTotalRed * regSoupValue / merchantTotalHorsePower;
            DateTime rndTime = redRecord.NextProductionTime.ToDateTime();
            redRecord.DayRedDrill = RedMakeHelp.GetTimeAndRed(rndTime, redNum).ToJson();
            redRecord.InvitationCodeNum = 0;
            redRecord.IsFinish = false;
            redRecord.TotalHorsePower = regSoupValue;
            context.UserSoupValueHis.Add(new UserSoupValueHis { CreateTime = unixdt, UserId = merchantId, TaskType = ETaskType.Auth, SoupValue = regSoupValue });

            //邀请人增加马力
            if (merchant.ParentId > 0)
            {
                var parentAuthinfo = GetAuth(merchant.ParentId);
                //var parentAuthinfo = context.AuthInfos.FirstOrDefault(c => c.MerchantId == merchant.ParentId);
                if (parentAuthinfo == null || (parentAuthinfo != null && parentAuthinfo.status != CertifyStatus.Auth))
                {
                    //可以发消息通知邀请人，因为没有实名所以没有加马力
                }
                else
                {
                    var parentRed = context.RedRecord.FirstOrDefault(c => c.MerchantId == merchant.ParentId);
                    if (parentRed != null)
                    {
                        var inviteSoup = context.SoupTask.FirstOrDefault(s => s.Type == ETaskType.InviteRegister);
                        inviteSoup.GetNum += 1;
                        UserSoupValueHis soupValue = new UserSoupValueHis();
                        var overInviteRegisterSoupValue = 1;
                        var inviteHorsePowerSetting = _iInviteHorsePowerSettingService.GetInviteHorsePowerSettingByTime(dt);
                        if (inviteHorsePowerSetting != null)
                            overInviteRegisterSoupValue = inviteHorsePowerSetting.horse_power;
                        soupValue.SoupValue = parentRed.InvitationCodeNum < 10 ? inviteSoup.SoupValue.GetValueOrDefault(10) : overInviteRegisterSoupValue;
                        soupValue.TaskType = ETaskType.InviteRegister;
                        soupValue.UserId = parentRed.MerchantId;
                        soupValue.CreateTime = unixdt;
                        context.UserSoupValueHis.Add(soupValue);
                        //邀请人增加马力与邀请数量+1
                        parentRed.TotalHorsePower = parentRed.TotalHorsePower + (parentRed.InvitationCodeNum < 10 ? inviteSoup.SoupValue.GetValueOrDefault(10) : overInviteRegisterSoupValue);
                        parentRed.InvitationCodeNum = parentRed.InvitationCodeNum + 1;
                        tags.Add("Merchant" + parentRed.MerchantId);
                    }
                }
            }
        }

        /// <summary>
        /// 后台注册--台湾号
        /// </summary>
        /// <param name="register_model"></param>
        /// <returns></returns>
        public bool TokenWebRegister(token_web_register_model register_model)
        {
            if (register_model.mobile_code != "886") throw new ServerErrorException("只能注册台湾号码");
            Regex rege = new Regex(@"^(13[0-9]|14[5-9]|15[012356789]|166|17[0-8]|18[0-9]|19[89])[0-9]{8}$");
            Regex rege2 = new Regex(@"^09\d{8}$");
            if (!rege.IsMatch(register_model.mobile) && !rege2.IsMatch(register_model.mobile))
            {
                throw new ServerErrorException("手机号不正确");
            }
            string oemMerchantNo = t_RequestMethod.merchant_no;
            var oem = context.Merchants.FirstOrDefault(c => c.MerchantNo == oemMerchantNo);
            var model = context.Merchants.FirstOrDefault(c => c.Mobile == register_model.mobile && c.IsOEM == false && c.OemId == oem.Id);
            if (model != null)
                throw new ServerErrorException("用户已经存在不可以注册");
            if (!string.IsNullOrEmpty(register_model.invitation_code) && register_model.invitation_code.Contains("0"))
            {//用户输入数字0替换成字母O，防止用户输错
                register_model.invitation_code = register_model.invitation_code.Replace("0", "O");
            }
            var parentRed = context.RedRecord.Where(s => s.InvitationCode == register_model.invitation_code).FirstOrDefault();
            if (parentRed == null) throw new ServerErrorException("邀请码不正确");

            if (register_model.mobile.Contains(t_RequestMethod.TestMobiePrefix)) throw new ServerErrorException("手机号不正确");
            var parent = context.Merchants.FindById(parentRed.MerchantId);
            DateTime dt = DateTime.Now;

            //用户
            model = new Merchant();
            model.Mobile = register_model.mobile;
            model.OpenId = model.MerchantNo = DateTime.Now.ToUnix() + DtoHelper.RandCode(4);
            model.CreateTime = model.LoginTime = DateTime.Now.ToUnix();
            model.AuthStatus = AuthStatusEnum.None;
            model.OemId = oem.Id;
            model.Name = register_model.mobile;
            model.ParentId = parent.Id;
            model.Setting = new merchant_setting().ToJson();
            model.PublicKey = model.Photo = model.Remark = string.Empty;
            string salt = Guid.NewGuid().ToString("N").Substring(12);
            model.PasswordSalt = salt;
            model.Password = WebHelper.GetPasswrodWithTwiceEncode(register_model.password, salt);
            model.UserType = UserType.user;
            model.IsOEM = model.IsPlatform = model.IsSupplier = model.TradeOutPay = false;
            model.MobileCode = register_model.mobile_code;
            var auth = context.AuthInfos.Where(s => s.Status == CertifyStatus.Auth && s.PayChannel == PayChannel.None);
            if (auth.FirstOrDefault(s => s.IdCard == register_model.card_no) != null) throw new ServerErrorException("该身份证已被实名认证");
            int flag = 0;
            string msg = string.Empty;
            //Regex reg = new Regex(@"^[a-zA-Z][0-9]{9}$");
            //if (!reg.IsMatch(register_model.card_no)) throw new ServerErrorException("身份证号码不正确");
            msg = "台湾";
            flag = 1;
            AuthInfo authinfo = new AuthInfo
            {
                OrderNo = string.Empty,
                PayChannel = PayChannel.None,
                MerchantId = model.Id,
                AccountNo = string.Empty,
                AccountName = register_model.user_name,
                Mobile = register_model.mobile,
                IdCard = register_model.card_no,
                Type = 3,
                Amount = 0,
                CreateTime = DateTime.Now.ToUnix(),
                Remark = msg,
                Status = flag == 1 ? CertifyStatus.Auth : CertifyStatus.Fail
            };

            //红钻
            RedRecord redRecord = new RedRecord();
            redRecord.CreateTime = redRecord.NextProductionTime = redRecord.RegisterTime = dt.ToUnix();
            var token = _settingService.GetTokenSetting().token;
            int dayTotalRed = token.day_total_red_drill;
            int merchantTotalHorsePower = token.total_horse_power;
            //初始用户30
            decimal redNum = (decimal)dayTotalRed * 30 / merchantTotalHorsePower;
            redRecord.DayRedDrill = RedMakeHelp.GetTimeAndRed(dt, redNum).ToJson();
            redRecord.InvitationCodeNum = 0;
            redRecord.IsFinish = false;
            redRecord.TotalHorsePower = 30;
            var soup = context.SoupTask.FirstOrDefault(s => s.Type == ETaskType.InviteRegister);
            soup.GetNum += 1;
            UserSoupValueHis soupValue = new UserSoupValueHis();
            soupValue.ItemId = 0;
            var overInviteRegisterSoupValue = 1;
            var inviteHorsePowerSetting = _iInviteHorsePowerSettingService.GetInviteHorsePowerSettingByTime(DateTime.Now);
            if (inviteHorsePowerSetting != null)
            {
                overInviteRegisterSoupValue = inviteHorsePowerSetting.horse_power;
            }
            soupValue.SoupValue = parentRed.InvitationCodeNum < 10 ? soup.SoupValue.GetValueOrDefault(10) : overInviteRegisterSoupValue;
            soupValue.TaskType = ETaskType.InviteRegister;
            soupValue.UserId = parentRed.MerchantId;
            soupValue.CreateTime = DateTime.Now.ToUnix();
            context.UserSoupValueHis.Add(soupValue);
            //红钻
            parentRed.TotalHorsePower = parentRed.TotalHorsePower + (parentRed.InvitationCodeNum < 10 ? soup.SoupValue.GetValueOrDefault(10) : overInviteRegisterSoupValue);
            parentRed.InvitationCodeNum = parentRed.InvitationCodeNum + 1;
            //用户邀请记录
            UserInvitationHis userInvitationHis = new UserInvitationHis();
            userInvitationHis.InvitationCode = register_model.invitation_code;

            userInvitationHis.InvitedUserId = parent.Id;
            userInvitationHis.CreateTime = DateTime.Now;

            var trans = context.Database.BeginTransaction();
            try
            {
                IEnumerable<merchant_dto> parents = new List<merchant_dto>();
                int depth = 1;
                if (model.ParentId > 0)
                {
                    parents = GetParents(model.ParentId);
                    depth = parents.Count() + 1;
                }
                model.Depth = depth;
                context.Merchants.Add(model);
                int r = _iUnitOfWork.Commit();
                //增加关系
                List<MemberPath> memberPaths = new List<MemberPath>();
                //新用户id也加入
                memberPaths.Add(new MemberPath { MemberId = model.Id, ParentId = model.Id });
                //增加上下级关系
                foreach (var item in parents)
                    memberPaths.Add(new MemberPath { MemberId = model.Id, ParentId = item.id });
                context.MemberPaths.AddRange(memberPaths);
                authinfo.MerchantId = model.Id;
                context.AuthInfos.Add(authinfo);

                //增加钻记录
                redRecord.MerchantId = model.Id;
                redRecord.InvitationCode = InvitationCodeHelp.toSerialCode(model.Id);
                context.RedRecord.Add(redRecord);
                //增加实名记录
                authinfo.MerchantId = model.Id;
                context.AuthInfos.Add(authinfo);
                //增加邀请记录
                userInvitationHis.UserId = model.Id;
                context.UserInvitationHis.Add(userInvitationHis);
                int r1 = _iUnitOfWork.Commit();
                if (r > 0 && r1 > 0)
                {
                    trans.Commit();
                    return true;
                }
                else return false;
            }
            catch (Exception ex)
            {
                trans.Rollback();
                var log = IocHelper.Get<ILogHelper>("data_error");
                log.Error(model.Mobile + "注册失败");
                log.Error(ex.Message, ex);
                return false;
            }
        }

        /// <summary>
        /// 短信验证码登录--原注册三步走业务
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        public merchant_dto TokenLoginByCode(token_login_model login_model)
        {
            _settingService.ValidCode(login_model.mobile, login_model.code, "token_login_code");
            int result = 0;
            string oemMerchantNo = t_RequestMethod.merchant_no;
            var oem = context.Merchants.FirstOrDefault(c => c.MerchantNo == oemMerchantNo);
            var model = context.Merchants.FirstOrDefault(c => c.Mobile == login_model.mobile && c.IsOEM == false && c.OemId == oem.Id);

            if (model == null) throw new ServerErrorException("用户不存在");
            if (model.Disabled)
                throw new ServerErrorException("商户已禁用");
            model.LoginTime = DateTime.Now.ToUnix();
            result = _iUnitOfWork.Commit("Merchant" + model.Id);
            _settingService.RemoveCode(login_model.mobile, "token_login_code");
            return Get(model.Id);
        }

        /// <summary>
        /// token 登录或注册--原注册三步走业务
        /// </summary>
        /// <param name="mobile"></param>
        /// <param name="code"></param>
        /// <returns></returns>
        public merchant_dto TokenLogin(string mobile, string code, string mobile_code = "86")
        {
            throw new ServerErrorException("已经停止此注册方式的版本，请更新最新版本，谢谢");
            //if (string.IsNullOrEmpty(mobile))
            //    throw new ServerErrorException("手机号码没有填写");
            //if (string.IsNullOrEmpty(code))
            //    throw new ServerErrorException("验证码没有填写");
            //_settingService.ValidCode(mobile, code, "token_login");
            //int result = 0;
            //string oemMerchantNo = t_RequestMethod.merchant_no;
            //var oem = context.Merchants.FirstOrDefault(c => c.MerchantNo == oemMerchantNo);
            ////已注册
            //var model = context.Merchants.FirstOrDefault(c => c.Mobile == mobile && c.IsOEM == false && c.OemId == oem.Id);
            //DateTime dt = DateTime.Now;
            //if (model != null) {
            //    if (model.Disabled)
            //        throw new ServerErrorException("用户已禁用");
            //    model.LoginTime = DateTime.Now.ToUnix();
            //    var tags = new List<string>();
            //    tags.Add("Merchant" + model.Id);
            //    result = _iUnitOfWork.Commit(tags.ToArray());
            //} else {
            //    if (mobile.Contains(t_RequestMethod.TestMobiePrefix)) throw new ServerErrorException("手机号不正确");
            //    model = new Merchant();
            //    model.Mobile = mobile;
            //    model.OpenId = model.MerchantNo = DateTime.Now.ToUnix() + DtoHelper.RandCode(4);
            //    model.CreateTime = model.LoginTime = DateTime.Now.ToUnix();
            //    model.AuthStatus = AuthStatusEnum.None;
            //    model.OemId = oem.Id;
            //    model.Name = mobile;
            //    model.ParentId = 0;
            //    model.Depth = 1;
            //    model.Setting = new merchant_setting().ToJson();
            //    model.PublicKey = model.Photo = model.Remark = model.Password = model.PasswordSalt = string.Empty;
            //    model.UserType = UserType.user;
            //    model.IsOEM = model.IsPlatform = model.IsSupplier = model.TradeOutPay = false;
            //    model.MobileCode = mobile_code;
            //    _settingService.RemoveCode(mobile, "token_login");
            //    RedRecord red = new RedRecord();
            //    red.CreateTime = red.NextProductionTime = red.RegisterTime = dt.ToUnix();
            //    var token = _settingService.GetTokenSetting().token;
            //    int dayTotalRed = token.day_total_red_drill;
            //    int merchantTotalHorsePower = token.total_horse_power;
            //    //初始用户30
            //    decimal redNum = (decimal)dayTotalRed * 30 / merchantTotalHorsePower;
            //    red.DayRedDrill = RedMakeHelp.GetTimeAndRed(dt, redNum).ToJson();
            //    red.InvitationCodeNum = 0;
            //    red.IsFinish = false;
            //    red.TotalHorsePower = 30;
            //    var trans = context.Database.BeginTransaction();
            //    try {
            //        context.Merchants.Add(model);
            //        int r = _iUnitOfWork.Commit();
            //        red.MerchantId = model.Id;
            //        red.InvitationCode = InvitationCodeHelp.toSerialCode(model.Id);
            //        context.RedRecord.Add(red);
            //        //增加关系
            //        context.MemberPaths.Add(new MemberPath { MemberId = model.Id, ParentId = model.Id });
            //        result = _iUnitOfWork.Commit();
            //        if (r > 0 && result > 0)
            //            trans.Commit();
            //    } catch (Exception ex) {
            //        trans.Rollback();
            //        var log = IocHelper.Get<ILogHelper>("data_error");
            //        log.Error(model.Mobile + "注册失败");
            //        log.Error(ex.Message, ex);
            //    }
            //    if (result == 0) throw new ServerErrorException("登录失败");
            //}
            //return model.ToDtoObject<merchant_dto>();
        }

        /// <summary>
        /// token 实名认证--原注册三步走业务
        /// </summary>
        /// <returns></returns>
        public Task<bool> VerificationNoCard(token_cardno_model model, long merchantId)
        {
            throw new ServerErrorException("已经停止此实名认证方式的版本，请更新最新版本，谢谢");
            //            var merchant = context.Merchants.FirstOrDefault(s => s.Id == merchantId);
            //            var auth = context.AuthInfos.Where(s => s.Status == CertifyStatus.Auth && s.PayChannel == PayChannel.None && s.MerchantId != 0);
            //            if (auth.FirstOrDefault(s => s.MerchantId == merchantId) != null) throw new ServerErrorException("您已实名认证");
            //            if (auth.FirstOrDefault(s => s.IdCard == model.card_no) != null) throw new ServerErrorException("该身份证已被实名认证");
            //            AuthInfo authinfo = new AuthInfo {
            //                OrderNo = string.Empty, PayChannel = PayChannel.None, MerchantId = merchant.Id, AccountNo = string.Empty, AccountName = model.user_name,
            //                Mobile = merchant.Mobile, IdCard = model.card_no, Type = 1, Amount = 0, CreateTime = DateTime.Now.ToUnix()
            //            };
            //            int flag = 0;
            //            if (merchant.MobileCode == "86") {
            //                var content = new Dictionary<string, string>();
            //                content.Add("username", "zs_20180528");
            //                content.Add("apikey", "2c1eab15e9df2499c03f52fad60bde01");
            //                content.Add("name", model.user_name);
            //                content.Add("id", model.card_no);
            //                var formUrlContent = new FormUrlEncodedContent(content);
            //#if DEBUG
            //                var result = await Task.FromResult(new bank_api_result { guid = "test", MESSAGE = "成功啦", RESULT = "1" });
            //#else
            //                var result = await t_RequestMethod.bankapi.PostAsync(formUrlContent).ReceiveJson<bank_api_result>();
            //#endif
            //                if (result != null) {
            //                    authinfo.Status = result.RESULT == "1" ? CertifyStatus.Auth : CertifyStatus.Fail;
            //                    authinfo.Remark = result.MESSAGE + "***" + result.RESULT + "***" + result.guid;
            //                    context.AuthInfos.Add(authinfo);
            //                    flag = _iUnitOfWork.Commit();
            //                    if (result.RESULT != "1") throw new ServerErrorException("实名认证失败,请输入正确的身份证和姓名");
            //                    return result.RESULT == "1" && flag > 0 ? true : false;
            //                } else {
            //                    throw new ServerErrorException("实名认证失败");
            //                }
            //            } else {
            //                Regex reg = new Regex(@"^[a-zA-Z][0-9]{9}$");
            //                if (!reg.IsMatch(model.card_no)) throw new ServerErrorException("身份证号码不正确");
            //                authinfo.Remark = "台湾";
            //                authinfo.Status = CertifyStatus.Auth;
            //                flag = _iUnitOfWork.Commit();
            //                return flag > 0;
            //            }
        }

        private static readonly object objkey = new object();
        /// <summary>
        /// 邀请码认证--原注册三步走业务
        /// </summary>
        /// <param name="dto"></param>
        /// <param name="merchantId"></param>
        /// <returns></returns>
        public bool InvitationCode(token_invitation_code_model dto, long merchantId)
        {
            lock (objkey)
            {
                using (var trans = context.Database.BeginTransaction())
                {
                    try
                    {
                        #region MyRegion
                        var model = context.Merchants.FirstOrDefault(s => s.Id == merchantId);
                        int result = 0;
                        var oemer = Get(t_RequestMethod.merchant_no);
                        bool ishas = context.Merchants.Exist(s => s.OemId == oemer.id && s.Name == dto.nick_name && s.Id != merchantId);
                        if (ishas) throw new ServerErrorException("昵称已存在");
                        //根据0生成 初始验证码
                        if (dto.invitation_code == "Qo9dZV")
                        {
                            model.Name = dto.nick_name;
                            result = _iUnitOfWork.Commit();
                        }
                        else
                        {
                            model.Name = dto.nick_name;
                            if (!string.IsNullOrEmpty(dto.invitation_code) && dto.invitation_code.Contains("0"))
                            {//用户输入数字0替换成字母O，防止用户输错
                                dto.invitation_code = dto.invitation_code.Replace("0", "O");
                            }
                            var red = context.RedRecord.Where(s => s.InvitationCode == dto.invitation_code).FirstOrDefault();
                            if (red == null) throw new ServerErrorException("邀请码不正确");
                            else
                            {
                                //if (red.InvitationCodeNum <= 0) throw new ServerErrorException("邀请码已失效");
                                var parent = context.Merchants.FindById(red.MerchantId);
                                if (model.ParentId > 0) throw new ServerErrorException("已有邀请人");
                                //if (merchant.Id == parent.Id) throw new ServerErrorException("邀请人不能是自己");
                                //if (merchant.ParentId == parent.Id) throw new ServerErrorException("已有邀请人");
                                model.ParentId = parent.Id;
                                var tags = new List<string>();
                                //if (red.InvitationCodeNum > 0) { }
                                var soup = context.SoupTask.FirstOrDefault(s => s.Type == ETaskType.InviteRegister);
                                soup.GetNum += 1;
                                var overInviteRegisterSoupValue = 1;
                                var inviteHorsePowerSetting = _iInviteHorsePowerSettingService.GetInviteHorsePowerSettingByTime(DateTime.Now);
                                if (inviteHorsePowerSetting != null)
                                {
                                    overInviteRegisterSoupValue = inviteHorsePowerSetting.horse_power;
                                }
                                UserSoupValueHis soupValue = new UserSoupValueHis();
                                soupValue.ItemId = 0;
                                soupValue.SoupValue = red.InvitationCodeNum < 10 ? soup.SoupValue.GetValueOrDefault(10) : overInviteRegisterSoupValue;
                                soupValue.TaskType = ETaskType.InviteRegister;
                                soupValue.UserId = red.MerchantId;
                                soupValue.CreateTime = DateTime.Now.ToUnix();
                                context.UserSoupValueHis.Add(soupValue);
                                //红钻
                                //red.InvitationCodeNum = red.InvitationCodeNum - 1;

                                // red.TotalHorsePower += soupValue.SoupValue;
                                red.TotalHorsePower = red.TotalHorsePower + (red.InvitationCodeNum < 10 ? soup.SoupValue.GetValueOrDefault(10) : overInviteRegisterSoupValue);
                                red.InvitationCodeNum = red.InvitationCodeNum + 1;
                                //用户邀请记录
                                UserInvitationHis user = new UserInvitationHis();
                                user.InvitationCode = dto.invitation_code;
                                user.UserId = model.Id;
                                user.InvitedUserId = parent.Id;
                                user.CreateTime = DateTime.Now;
                                context.UserInvitationHis.Add(user);
                                tags.Add("Merchant" + model.Id);
                                var re = context.Database.ExecuteSqlCommand("exec sp_member_update_path @p0,@p1", merchantId, parent.Id);
                                if (re > 0)
                                    result = _iUnitOfWork.Commit(tags.ToArray());
                            }
                        }
                        trans.Commit();
                        #endregion
                        return result > 0;
                    }
                    catch (Exception ex)
                    {
                        trans.Rollback();
                        var log = IocHelper.Get<ILogHelper>("data_error");
                        log.Error(ex.Message, ex);
                        return false;
                    }
                }
            }
        }

        /// <summary>
        /// 风信子--没有用了
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        public Task<bool> VNoCard(fengxinzi_cardno_model model)
        {
            //var content = new Dictionary<string, string>();
            //content.Add("username", "zs_20180528");
            //content.Add("apikey", "2c1eab15e9df2499c03f52fad60bde01");
            //content.Add("name", model.user_name);
            //content.Add("id", model.card_no);
            //var formUrlContent = new FormUrlEncodedContent(content);
            //var result = await t_RequestMethod.bankapi.PostAsync(formUrlContent).ReceiveJson<bank_api_result>();
            //if (result != null) {
            //    var log = IocHelper.Get<ILogHelper>("info");
            //    log.Info(model.mobile + "---" + model.card_no + "---" + model.user_name + "---" + result.MESSAGE);
            //    if (result.RESULT != "1") throw new ServerErrorException("实名认证失败,请输入正确的身份证和姓名");
            //    return result.RESULT == "1";
            //} else {
            //    throw new ServerErrorException("实名认证失败");
            //}
            return Task.FromResult(true);
        }

        /// <summary>
        /// 获取 token  用户
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public token_user_info GetTokenUser(long id)
        {
            token_user_info user = new token_user_info();
            var model = Get(id);
            bool isTestMobile = model.mobile.Contains(t_RequestMethod.TestMobiePrefix);
            int startIndex = 0; int length = 0;
            if (model.mobile_code == "86") { startIndex = 3; length = 7; }
            else
            {
                startIndex = 2; length = 5;
            }
            var auth = GetAuth(id);
            user.user_name = auth != null && !string.IsNullOrEmpty(auth.account_name) ? auth.account_name.Replace(auth.account_name.Substring(0, 1), "*") : string.Empty;
            user.card_no = auth != null && !string.IsNullOrEmpty(auth.id_card) ? auth.id_card.Replace(auth.id_card.Substring(startIndex, auth.id_card.Length - length), "****") : string.Empty;
            user.is_verify_no_card = isTestMobile == true ? true : (auth != null && auth.status == CertifyStatus.Auth ? true : false);
            user.status = auth != null ? auth.status : CertifyStatus.None;
            user.type = auth != null ? auth.certificate_type : 1;
            user.remark = auth != null ? auth.remark : "";
            user.card_img = auth != null ? auth.card_img : "";
            user.mobile = model.mobile.Replace(model.mobile.Substring(3, 4), "****");
            user.nick_name = model.name;
            user.is_verify_invitation_code = isTestMobile == true ? true : model.parent_id > 0;
            user.photo = model.photo;
            user.qrcode_url = t_RequestMethod.invitation_register_url + "?m=" + model.id;
            user.help_url = t_RequestMethod.help_url;
            user.my_friend_url = t_RequestMethod.my_friend_url;
            user.shipping_url = t_RequestMethod.shipping_url;
            user.parent_id = model.parent_id;
            user.is_show_shop = model.is_supplier;
            user.disabled = model.disabled;
            user.is_face = model.is_face;
            user.is_pay = context.Orders.Any(s => s.BuyId == id && s.Status == OrderStatus.WaitDelivery && s.OrderType == 7);
            return user;
        }

        /// <summary>
        /// 上传完整的进件信息并创建商户
        /// </summary>
        /// <returns>The create.</returns>
        /// <param name="dto">Dto.</param>
        public verify_auth_result Auth(verify_auth_model dto)
        {
            var model = new batch_auth_model();
            model.merchant_no = dto.merchant_no;
            model.type = dto.type;
            model.data.Add(dto.ToDtoObject<batch_auth_model_item>());
            var result = Auth(model);
            return result.FirstOrDefault();
        }

        /// <summary>
        /// 上传完整的进件信息并创建商户
        /// </summary>
        /// <returns>The create.</returns>
        /// <param name="models">Dto.</param>
        public List<verify_auth_result> Auth(batch_auth_model models)
        {
            if (models.data.Count > 100)
                throw new ServerErrorException("商户进件不得超过100条");
            var auth_result = new List<verify_auth_result>();
            var trans = context.Database.BeginTransaction();
            try
            {
                var tags = new List<string>();
                foreach (var dto in models.data)
                {
                    var oemer = Get(models.merchant_no);
                    Merchant model = null;
                    var first = dto.payments.Select(c => new { c.code, c.channel, c.settle_type }).Distinct().Count();
                    if (first != dto.payments.Count)
                        throw new ServerErrorException("结算方式不能是一样的");
                    if (models.type == "add")
                    {
                        if (context.Merchants.Exist(c => c.OpenId == dto.openid && c.OemId == oemer.id))
                            throw new ServerErrorException("商户已经存在不可以注册");
                        model = new Merchant();
                        model.MobileCode = string.IsNullOrEmpty(model.MobileCode) ? "86" : model.MobileCode;
                        model.OpenId = dto.openid;
                        model.Mobile = dto.reg_mobile;
                        model.Name = dto.account_name;
                        model.CreateTime = model.LoginTime = DateTime.Now.ToUnix();
                        model.MerchantNo = DateTime.Now.ToUnix() + DtoHelper.RandCode(4);
                        var auth_info = dto.ToDtoObject<auth_info_setting>();
                        auth_info.card_handheld = dto.card_handheld;
                        auth_info.card_negative = dto.card_negative;
                        auth_info.card_positive = dto.card_positive;
                        auth_info.bank_negative = dto.bank_negative;
                        auth_info.bank_positive = dto.bank_positive;
                        auth_info.start_time = dto.start_time;
                        auth_info.end_time = dto.end_time;
                        var merchant_set = new merchant_setting { auth_info = auth_info };
                        model.AuthStatus = AuthStatusEnum.Wait;
                        model.Setting = merchant_set.ToJson();
                        model.UserType = UserType.user;
                        model.ParentId = 0;
                        model.Depth = 1;
                        model.OemId = oemer.id;
                        var pay_ids = new Dictionary<long, List<settle_setting>>();
                        var p_payments = _iPaymentService.Get();
                        foreach (var payment in dto.payments)
                        {
                            var pay = p_payments.FirstOrDefault(c => c.channel == payment.channel && c.settles.Any(p => p.code == payment.code));
                            if (pay_ids.ContainsKey(pay.id))
                            {
                                var new_item = pay_ids[pay.id];
                                if (string.IsNullOrEmpty(payment.settle_type))
                                    throw new ServerErrorException("结算方式不能空");
                                if (!string.IsNullOrEmpty(payment.settle_type) && payment.settle_type != "T0" && payment.settle_type != "T1")
                                    throw new ServerErrorException("结算方式必须是T0或T1");
                                new_item.Add(new settle_setting { code = payment.code, fee = payment.fee, settle = payment.settle, settle_type = payment.settle_type });
                            }
                            else
                            {
                                if (!string.IsNullOrEmpty(payment.settle_type) && (payment.settle_type != "T0" && payment.settle_type != "T1"))
                                    throw new ServerErrorException("结算方式必须是T0或T1");
                                pay_ids.Add(pay.id, new List<settle_setting>{ new settle_setting {
                                code = payment.code, fee = payment.fee, settle = payment.settle,
                                settle_type = string.IsNullOrEmpty(payment.settle_type) ? "T0" : payment.settle_type
                            }});
                            }
                        }

                        context.Merchants.Add(model);
                        int result2 = _iUnitOfWork.Commit(tags.ToArray());
                        //增加支付方式
                        foreach (var item in pay_ids)
                            context.MerchantPayments.Add(new MerchantPayment { MerchantId = model.Id, PaymentId = item.Key, Settles = item.Value.ToJson() });
                        //增加关系
                        context.MemberPaths.Add(new MemberPath { MemberId = model.Id, ParentId = model.Id });
                        result2 = _iUnitOfWork.Commit();
                    }
                    else
                    {
                        model = context.Merchants.FirstOrDefault(c => c.OpenId == dto.openid && c.OemId == oemer.id);
                        if (model == null)
                            throw new ServerErrorException("商户不存在");
                        if (model.IsOEM)
                            throw new ServerErrorException("O商户不需要进件");
                        model.Mobile = dto.reg_mobile;
                        model.Name = dto.account_name;
                        var merchant_set = model.Setting.ToObject<merchant_setting>();
                        merchant_set.auth_info = dto.ToDtoObject<auth_info_setting>();
                        if (!string.IsNullOrEmpty(dto.card_handheld)) merchant_set.auth_info.card_handheld = dto.card_handheld;
                        if (!string.IsNullOrEmpty(dto.card_negative)) merchant_set.auth_info.card_negative = dto.card_negative;
                        if (!string.IsNullOrEmpty(dto.card_positive)) merchant_set.auth_info.card_positive = dto.card_positive;
                        if (!string.IsNullOrEmpty(dto.bank_negative)) merchant_set.auth_info.bank_negative = dto.bank_negative;
                        if (!string.IsNullOrEmpty(dto.bank_positive)) merchant_set.auth_info.bank_positive = dto.bank_positive;
                        if (!string.IsNullOrEmpty(dto.start_time)) merchant_set.auth_info.start_time = dto.start_time;
                        if (!string.IsNullOrEmpty(dto.end_time)) merchant_set.auth_info.end_time = dto.end_time;
                        if (dto.no_auth == 0 && model.AuthStatus != AuthStatusEnum.Auth)
                            model.AuthStatus = AuthStatusEnum.Wait;
                        model.Setting = merchant_set.ToJson();
                        var pay_ids = new Dictionary<long, merchant_payment>();
                        foreach (var payment in dto.payments)
                        {
                            var p_payments = _iPaymentService.Get();
                            var pay = p_payments.FirstOrDefault(c => c.channel == payment.channel && c.settles.Any(p => p.code == payment.code));
                            if (pay_ids.ContainsKey(pay.id))
                            {
                                var new_item = pay_ids[pay.id];
                                if (string.IsNullOrEmpty(payment.settle_type))
                                    throw new ServerErrorException("结算方式不能空");
                                if (!string.IsNullOrEmpty(payment.settle_type) && payment.settle_type != "T0" && payment.settle_type != "T1")
                                    throw new ServerErrorException("结算方式必须是T0或T1");
                                new_item.settles.Add(new settle_setting { code = payment.code, fee = payment.fee, settle = payment.settle, settle_type = payment.settle_type });
                            }
                            else
                            {
                                if (!string.IsNullOrEmpty(payment.settle_type) && (payment.settle_type != "T0" && payment.settle_type != "T1"))
                                    throw new ServerErrorException("结算方式必须是T0或T1");
                                pay_ids.Add(pay.id, new merchant_payment
                                {
                                    channel = payment.channel,
                                    settles = new List<settle_setting> {
                                new settle_setting{ code = payment.code, fee =  payment.fee, settle = payment.settle,
                                settle_type = string.IsNullOrEmpty(payment.settle_type)?"T0":payment.settle_type}
                            }
                                });
                            }
                        }
                        var merchantPayments = context.MerchantPayments.Where(c => c.MerchantId == model.Id).ToList();
                        if (pay_ids.Count > 0)
                        {
                            var payment_ids = pay_ids.Select(c => c.Key);
                            var data_ids = merchantPayments.Select(c => c.PaymentId).CopyToList();
                            var oemer_payments = GetPayments(oemer.id);
                            //新增
                            payment_ids.Except(data_ids).DataForEach(filter_id =>
                            {
                                var new_item = pay_ids[filter_id];
                                //级别的费率或结算费不能低于上级商户
                                var payment = oemer_payments.FirstOrDefault(c => c.payment_id == filter_id);
                                if (payment != null)
                                {
                                    foreach (var settle in payment.settles)
                                    {
                                        var grade_settle = new_item.settles.FirstOrDefault(c => c.settle_type == settle.settle_type);
                                        if (grade_settle != null)
                                        {
                                            if (grade_settle.fee < settle.fee)
                                                throw new ServerErrorException("级别的费率不能低于商户");
                                            if (grade_settle.settle < settle.settle)
                                                throw new ServerErrorException("级别的结算费不能低于商户");
                                        }
                                    }
                                }
                                context.MerchantPayments.Add(new MerchantPayment { MerchantId = model.Id, PaymentId = filter_id, Settles = new_item.settles.ToJson() });
                            });
                            //删除
                            data_ids.Except(payment_ids).DataForEach(filter_id =>
                            {
                                var item = merchantPayments.First(c => c.PaymentId == filter_id);
                                context.Entry(item).State = EntityState.Deleted;
                            });
                            //更新
                            payment_ids.Intersect(data_ids).DataForEach(filter_id =>
                            {
                                var new_item = pay_ids[filter_id];
                                //级别的费率或结算费不能低于上级商户
                                var payment = oemer_payments.FirstOrDefault(c => c.payment_id == filter_id);
                                if (payment != null)
                                {
                                    foreach (var settle in payment.settles)
                                    {
                                        var grade_settle = new_item.settles.FirstOrDefault(c => c.settle_type == settle.settle_type);
                                        if (grade_settle != null)
                                        {
                                            if (grade_settle.fee < settle.fee)
                                                throw new ServerErrorException("级别的费率不能低于上级商户");
                                            if (grade_settle.settle < settle.settle)
                                                throw new ServerErrorException("级别的结算费不能低于上级商户");
                                        }
                                    }
                                }
                                var item = merchantPayments.First(c => c.PaymentId == filter_id);
                                if (item != null)
                                {
                                    item.Settles = new_item.settles.ToJson();
                                    context.Entry(item).State = EntityState.Modified;
                                }
                            });
                        }
                        else
                        {
                            //如果原来有数据，删除
                            if (merchantPayments.Count > 0)
                                merchantPayments.DataForEach(item => { context.Entry(item).State = EntityState.Deleted; });
                        }
                        //修改关系
                        //context.Database.ExecuteSqlCommand("exec sp_member_update_path @p0,@p1", model.Id, model.ParentId);
                        tags.Add("Merchant" + model.Id);
                        tags.Add("Merchant" + model.MerchantNo);
                    }
                    auth_result.Add(new verify_auth_result { openid = dto.openid, merchant_no = model.MerchantNo, status = model.AuthStatus });
                    int result = _iUnitOfWork.Commit(tags.ToArray());
                }
                trans.Commit();
            }
            catch (Exception ex)
            {
                trans.Rollback();
                var log = IocHelper.Get<ILogHelper>("data_error");
                log.Error(ex.Message, ex);
            }
            return auth_result;
        }

        /// <summary>
        /// 四要素订单
        /// </summary>
        /// <param name="model">Model.</param>
        /// <param name="remark">Remark.</param>
        public void CertifyVerify(certify_verify model, string remark)
        {
            var merchant = context.Merchants.FirstOrDefault(c => c.MerchantNo == model.bind_no);
            merchant.IsCertify = 1;
            if (model.status == CertifyStatus.Auth)
                merchant.AuthStatus = AuthStatusEnum.Auth;
            else
                merchant.Remark = remark;

            context.AuthInfos.Add(new AuthInfo
            {
                OrderNo = model.order_no,
                PayChannel = model.pay_channel,
                MerchantId = merchant.Id,
                AccountNo = model.account_no,
                AccountName = model.account_name,
                Mobile = model.mobile,
                IdCard = model.id_card,
                Type = model.card_type == 0 ? 1 : model.card_type,
                Amount = model.amount,
                Remark = remark,
                Status = model.status,
                CreateTime = DateTime.Now.ToUnix()
            });

            int result = _iUnitOfWork.Commit("Merchant" + merchant.Id, "Merchant" + merchant.MerchantNo);
        }

        /// <summary>
        /// 实名认证列表
        /// </summary>
        /// <returns>The get.</returns>
        /// <param name="query">Query.</param>
        public PagedResult<authinfo_dto> Get(MemberQuery query)
        {
            var filter = PredicateBuilder.True<AuthInfo>();
            if (!string.IsNullOrEmpty(query.name))
                filter = filter.And(c => c.AccountName == query.name);
            if (!string.IsNullOrEmpty(query.mobile))
                filter = filter.And(c => c.Mobile == query.mobile);
            if (!string.IsNullOrEmpty(query.idcard))
                filter = filter.And(c => c.IdCard == query.idcard);
            var start_time = query.start_time.ToUnix();
            if (query.start_time.HasValue && query.end_time.HasValue)
            {
                var end_time = query.end_time.Value.AddDays(1).ToUnix();
                filter = filter.And(c => c.CreateTime >= start_time && c.CreateTime <= end_time);
            }
            else if (query.start_time.HasValue && !query.end_time.HasValue)
                filter = filter.And(c => c.CreateTime >= start_time);
            else if (!query.start_time.HasValue && query.end_time.HasValue)
            {
                var end_time = query.end_time.Value.AddDays(1).ToUnix();
                filter = filter.And(c => c.CreateTime <= end_time);
            }
            if (!string.IsNullOrEmpty(query.type))
            {
                int value = int.Parse(query.type);
                filter = filter.And(c => c.CertificateType == value);
            }
            if (!string.IsNullOrEmpty(query.status))
            {
                int value = int.Parse(query.status);
                filter = filter.And(c => c.Status == (CertifyStatus)value);
            }
            var result = context.AuthInfos.FromCachePaged<AuthInfo, authinfo_dto>(query.page, query.size, filter, orderBy => orderBy.OrderBy(o => o.Status).ThenByDescending(c => c.Id));
            return result;
        }

        /// <summary>
        /// 实名认证后台审核
        /// </summary>
        /// <param name="dto"></param>
        /// <param name="manageId"></param>
        /// <returns></returns>
        public bool AuthInfoAudit(authinfo_dto dto, long manageId)
        {
            var authInfo = context.AuthInfos.FindById(dto.id);
            if (authInfo.Status != CertifyStatus.UnConfirm)
                throw new ServerErrorException("当前记录非待审核状态，不能进行审核操作");
            if (dto.status == CertifyStatus.Fail)
            {
                if (string.IsNullOrEmpty(dto.remark))
                    throw new ServerErrorException("请输入审核不通过的备注");
            }
            if (dto.status == CertifyStatus.UnConfirm && dto.status == authInfo.Status)//未做任何修改，不要发消息
                return false;
            List<string> cacheTags = new List<string>() { "Merchant" + authInfo.MerchantId };
            if (dto.status != CertifyStatus.UnConfirm)
            {
                authInfo.Status = dto.status;
                authInfo.Remark = dto.remark;
                var manager = context.Manages.FindById(manageId);
                authInfo.AuditUserMobile = manager.Mobile;
                authInfo.AuditTime = DateTime.Now.ToUnix();
            }
            if (authInfo.Status == CertifyStatus.Auth)
            {//审核通过
                if (!context.UserSoupValueHis.Exist(o => o.UserId == authInfo.MerchantId && o.TaskType == ETaskType.Auth))
                {//未完成过实名任务
                    //实名认证审核通过处理（初始化用户马力、红钻、完成实名任务）
                    var dt = DateTime.Now;
                    var unixdt = dt.ToUnix();
                    AuthInfoApprovedHandle(authInfo.MerchantId, dt, unixdt, authInfo.Merchant, cacheTags);
                }
            }
            //保存消息
            var replyMessage = new MessagePush();
            replyMessage.MerchantId = authInfo.MerchantId;
            replyMessage.Type = MsgType.CertifyPass;
            if (dto.status == CertifyStatus.Auth)
            {
                replyMessage.Title = "实名审核通过";
                replyMessage.ShortContent = "您已通过实名审核，获取30马力，开启拓垦之旅吧！";
                replyMessage.Content = "您已通过实名审核，获取30马力，开启拓垦之旅吧！";
            }
            else
            {
                replyMessage.Title = "实名审核未通过";
                replyMessage.ShortContent = "您已通过实名未审核，请正确填写姓名身份证！";
                replyMessage.Content = dto.remark;
            }
            replyMessage.Ext = "{}";
            replyMessage.CreateTime = DateTime.Now.ToUnix();
            replyMessage.ObjectId = authInfo.MerchantId;
            context.MessagePushs.Add(replyMessage);

            //发送消息
            try
            {
                JPushHelp jPushHelp = new JPushHelp(t_RequestMethod.push_app_key, t_RequestMethod.push_app_secret);
                jPushHelp.Push(replyMessage.Title, replyMessage.Content, (int)replyMessage.Type, authInfo.MerchantId, new List<string> { authInfo.Merchant.Mobile });
            }
            catch (Exception) { }
            return _iUnitOfWork.Commit(cacheTags.ToArray()) > 0;
        }

        /// <summary>
        /// 重置认证次数
        /// </summary>
        /// <param name="authId"></param>
        /// <returns></returns>
        public bool ResetAuthNum(long authId)
        {
            var authInfo = context.AuthInfos.FindById(authId);
            if (authInfo.Status == CertifyStatus.Auth)
                throw new ServerErrorException("已通过认证，不允许重置认证次数");
            authInfo.Amount = 0;
            _iUnitOfWork.Commit("Merchant" + authInfo.MerchantId);
            return true;
        }

        /// <summary>
        /// 已确认实名
        /// </summary>
        /// <returns>The verifyed.</returns>
        /// <param name="id">Identifier.</param>
        public int CertifyVerifyed(long id)
        {
            var merchant = context.Merchants.Find(id);
            merchant.IsCertify = 2;
            int result = _iUnitOfWork.Commit("Merchant" + merchant.Id, "Merchant" + merchant.MerchantNo);
            return result;
        }

        /// <summary>
        /// 审核认证
        /// </summary>
        /// <returns>The auth.</returns>
        /// <param name="merchant_id">Merchant identifier.</param>
        /// <param name="auth_info">Auth info.</param>
        /// <param name="auth_status">Auth status.</param>
        /// <param name="msg">Message.</param>
        public async Task<int> Auth(long merchant_id, auth_info_setting auth_info, AuthStatusEnum auth_status, string msg = "")
        {
            var model = context.Merchants.Find(merchant_id);
            var old_auth = model.AuthStatus;

            var setting = model.Setting.ToObject<merchant_setting>();
#if !DEBUG
            //if (string.IsNullOrEmpty(setting.hx_merchant_no) && auth_status == AuthStatusEnum.Auth)
            //	throw new ServerErrorException("进件商户失败，注意名称、身份证、卡号是存正确");
#endif
            setting.auth_info = auth_info;
            model.Setting = setting.ToJson();
            model.AuthStatus = auth_status;
            if (auth_status != AuthStatusEnum.Auth && !string.IsNullOrEmpty(msg)) model.Remark = msg;
            else if (auth_status == AuthStatusEnum.Auth) model.Remark = "";

            if (!model.IsOEM && !model.IsPlatform && !string.IsNullOrEmpty(auth_info.notify))
            {
                try
                {
                    var data = auth_info.ToDtoObject<auth_info_result>();
                    data.id_card = data.id_card.ToUpper();
                    data.merchant_no = model.MerchantNo;
                    data.auth_status = auth_status;
                    data.result_msg = (auth_status == AuthStatusEnum.Auth ? "认证成功" : msg);
                    int result = _iUnitOfWork.Commit("Merchant" + model.Id, "Merchant" + model.MerchantNo);
                    var api_result = await auth_info.notify.PostJsonAsync(ApiResultToJson.Json(data)).ReceiveJson<ResultMessage<string>>();
                    if (api_result.result_code != 1000)
                    {
                        if (!api_result.result_msg.Contains("已通过认证"))
                        {
                            model.AuthStatus = old_auth;
                            _iUnitOfWork.Commit("Merchant" + model.Id, "Merchant" + model.MerchantNo);
                        }
                    }
                    return result;
                }
                catch (Exception ex)
                {
                    model.AuthStatus = old_auth;
                    _iUnitOfWork.Commit("Merchant" + model.Id, "Merchant" + model.MerchantNo);

                    var log = IocHelper.Get<ILogHelper>("info");
                    log.Error("认证通知失败:" + merchant_id);
                    log.Error(ex.Message);
                }
            }
            return 0;
        }

        /// <summary>
        /// 扫码认证
        /// </summary>
        /// <returns>The native.</returns>
        /// <param name="merchant_id">Merchant identifier.</param>
        /// <param name="auth_status">Auth status.</param>
        /// <param name="msg">Message.</param>
        public async Task<int> AuthNative(long merchant_id, AuthStatusEnum auth_status, string msg = "")
        {
            var model = context.Merchants.Find(merchant_id);
            var setting = model.Setting.ToObject<merchant_setting>();
            var old_open_wx = setting.hf_set.open_wx;
            if (auth_status == AuthStatusEnum.WaitAuth)
            {
                setting.hf_set.open_wx = auth_status;
                model.Setting = setting.ToJson();
                return _iUnitOfWork.Commit("Merchant" + model.Id, "Merchant" + model.MerchantNo);
            }
            if (auth_status != AuthStatusEnum.Auth && !string.IsNullOrEmpty(msg)) model.Remark = msg;
            else if (auth_status == AuthStatusEnum.Auth) model.Remark = "";
            //if (old_open_wx == AuthStatusEnum.Auth) return 1;
            setting.hf_set.open_wx = auth_status;
            if (!model.IsOEM && !model.IsPlatform && !string.IsNullOrEmpty(setting.hf_set.notify))
            {
                try
                {
                    var data = new native_merchant_notify();
                    data.merchant_no = model.MerchantNo;
                    data.status = auth_status;
                    data.result_msg = (auth_status == AuthStatusEnum.Auth ? "开通微信扫码认证成功" : msg);
                    var api_result = await setting.hf_set.notify.PostJsonAsync(ApiResultToJson.Json(data)).ReceiveJson<ResultMessage<string>>();
                    if (api_result.data != "OK")
                    {
                        setting.hf_set.open_wx = old_open_wx;
                    }
                    model.Setting = setting.ToJson();
                    int result = _iUnitOfWork.Commit("Merchant" + model.Id, "Merchant" + model.MerchantNo);
                    return result;
                }
                catch (Exception ex)
                {
                    setting.hf_set.open_wx = old_open_wx;
                    model.Setting = setting.ToJson();
                    _iUnitOfWork.Commit("Merchant" + model.Id, "Merchant" + model.MerchantNo);
                    var log = IocHelper.Get<ILogHelper>("info");
                    log.Error("开通微信扫码认证通知失败:" + merchant_id);
                    log.Error(ex.Message);
                }
            }
            return 0;
        }

        /// <summary>
        /// 保存修改认证信息
        /// </summary>
        /// <returns>The edit.</returns>
        /// <param name="merchant_id">Merchant identifier.</param>
        /// <param name="auth_info">Auth info.</param>
        public async Task<int> AuthEdit(long merchant_id, auth_info_setting auth_info)
        {
            int result = 0;
            var model = context.Merchants.Find(merchant_id);
            var setting = model.Setting.ToObject<merchant_setting>();
            setting.auth_info = auth_info;
            model.Name = auth_info.account_name;
            model.Setting = setting.ToJson();
            //return _iUnitOfWork.Commit("Merchant" + model.Id, "Merchant" + model.MerchantNo);
            //var model = context.Merchants.Find(merchant_id);
            try
            {
                string url = "http://api.timebiz.cn/open/notify_merchant";
                var data = new merchant_info_notify
                {
                    merchant_no = model.MerchantNo,
                    account_name = auth_info.account_name,
                    account_no = auth_info.account_no,
                    id_card = auth_info.id_card,
                    mobile = auth_info.mobile
                };
                var api_result = await url.PostJsonAsync(ApiResultToJson.Json(data)).ReceiveJson<ResultMessage<string>>();
                if (api_result.result_code == 1000)
                {
                    var merchantRegister = context.MerchantRegisters.Where(m => m.MerchantId == merchant_id && m.PayChannel == PayChannel.TenSubPay).FirstOrDefault();
                    if(merchantRegister != null)
                    {
                        merchantRegister.AccountName = data.account_name;
                        merchantRegister.AccountNo = data.account_no;
                        merchantRegister.IdCard = data.id_card;
                        merchantRegister.Mobile = data.mobile;
                    }
                    result = _iUnitOfWork.Commit();
                }
            }
            catch
            {

            }
            return result;
        }

        /// <summary>
        /// 找回密码
        /// </summary>
        /// <param name="forget">找回密码请求信息</param>
        /// <returns></returns>
        public bool Forget(forget_model forget)
        {
            if (string.IsNullOrEmpty(forget.mobile))
                throw new ServerErrorException("手机号码不能是空的");
            if (string.IsNullOrEmpty(forget.password))
                throw new ServerErrorException("密码不能是空的");
            if (string.IsNullOrEmpty(forget.re_password))
                throw new ServerErrorException("确认密码不能是空的");
            if (forget.password != forget.re_password)
                throw new ServerErrorException("密码和确认密码不一致");

            var oemer = Get(forget.oem_no);
            var model = context.Merchants.FirstOrDefault(c => c.Mobile == forget.mobile && c.OemId == oemer.id);
            if (model == null)
                throw new ServerErrorException("商户不存在");

            model.Password = WebHelper.GetPasswrodWithTwiceEncode(forget.password, model.PasswordSalt);

            int result = _iUnitOfWork.Commit();
            return result >= 0;
        }

        /// <summary>
        /// 修改密码
        /// </summary>
        /// <param name="user_id"></param>
        /// <param name="password"></param>
        /// <param name="re_password"></param>
        /// <returns></returns>
        public bool ChangePwd(long user_id, string old_password, string password, string re_password)
        {
            if (string.IsNullOrEmpty(password))
                throw new ServerErrorException("密码不能是空的");
            if (string.IsNullOrEmpty(re_password))
                throw new ServerErrorException("确认密码不能是空的");
            if (password != re_password)
                throw new ServerErrorException("密码和确认密码不一致");
            var model = context.Merchants.Find(user_id);
            if (model == null)
                throw new ServerErrorException("商户不存在");
            if (model.Password != WebHelper.GetPasswrodWithTwiceEncode(old_password, model.PasswordSalt))
                throw new ServerErrorException("原密码不正确");

            model.Password = WebHelper.GetPasswrodWithTwiceEncode(password, model.PasswordSalt);

            int result = _iUnitOfWork.Commit();
            return result >= 0;
        }

        /// <summary>
        /// token 后台修改密码
        /// </summary>
        /// <param name="modify_model"></param>
        /// <returns></returns>
        public bool TokenModifyPwd(token_modify_pwd_model modify_model)
        {
            var model = context.Merchants.FindById(modify_model.user_id);
            if (model == null) throw new ServerErrorException("用户不存在");
            string salt = Guid.NewGuid().ToString("N").Substring(12);
            model.PasswordSalt = salt;
            model.Password = WebHelper.GetPasswrodWithTwiceEncode(modify_model.password, salt);
            int result = _iUnitOfWork.Commit();
            return result > 0;
        }

        /// <summary>
        /// 更新商户信息,后台用
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        public int Update(merchant_info dto)
        {
            var trans = context.Database.BeginTransaction();
            try
            {
                var model = context.Merchants.FindById(dto.id);
                bool unchanged_Parent = dto.parent_id == model.ParentId;
                if (dto.usertype == UserType.distributor)
                {
                    dto.is_supplier = false;
                    dto.is_oem = false;
                    dto.is_platform = false;
                }
                else if (dto.usertype == UserType.supplier)
                    dto.is_supplier = true;
                else if (dto.usertype == UserType.oem)
                    dto.is_oem = true;
                dto.ToDtoObject(model);
                if (string.IsNullOrEmpty(model.MobileCode))
                    model.MobileCode = "86";
                #region 费率
                merchant_dto oemer = null;
                if (model.OemId.HasValue && model.OemId.Value > 0)
                {
                    oemer = Get(model.OemId.Value);
                    //如果是顶级就用通道的支付方式
                    //if (merchant.payments.Count == 0) {
                    //	var payments = _iPaymentService.Get();
                    //	foreach (var payment in payments) {
                    //		merchant.payments.Add(new merchant_payment_dto {
                    //			payment_id = payment.id,
                    //			settles = payment.settles.Select(c => new settle_setting { settle_type = c.settle_type, fee = c.fee, settle = c.settle }).ToList()
                    //		});
                    //	}
                    //}
                }
                if (model.IsOEM)
                {
                    oemer = Get(model.Id);
                }
                var payment_ids = dto.payments.Select(c => c.payment_id).ToList();
                var merchantPayments = context.MerchantPayments.Where(c => c.MerchantId == model.Id).ToList();
                if (payment_ids.Count > 0)
                {
                    var data_ids = merchantPayments.Select(c => c.PaymentId).CopyToList();
                    var oemer_payments = GetPayments(oemer.id);
                    //新增
                    payment_ids.Except(data_ids).DataForEach(filter_id =>
                    {
                        var new_item = dto.payments.First(c => c.payment_id == filter_id);
                        //级别的费率或结算费不能低于上级商户
                        if (oemer != null)
                        {
                            var payment = oemer_payments.FirstOrDefault(c => c.payment_id == new_item.payment_id);
                            if (payment != null)
                            {
                                foreach (var settle in payment.settles)
                                {
                                    var grade_settle = new_item.settles.FirstOrDefault(c => c.settle_type == settle.settle_type);
                                    if (grade_settle != null)
                                    {
                                        if (grade_settle.fee < settle.fee)
                                            throw new ServerErrorException("级别的费率不能低于上级商户");
                                        if (grade_settle.settle < settle.settle)
                                            throw new ServerErrorException("级别的结算费不能低于上级商户");
                                    }
                                }
                            }
                        }
                        context.MerchantPayments.Add(new MerchantPayment { MerchantId = dto.id, PaymentId = filter_id, Settles = new_item.settles.ToJson() });
                    });
                    //删除
                    data_ids.Except(payment_ids).DataForEach(filter_id =>
                    {
                        var item = merchantPayments.First(c => c.PaymentId == filter_id);
                        context.Entry(item).State = EntityState.Deleted;
                    });
                    //更新
                    payment_ids.Intersect(data_ids).DataForEach(filter_id =>
                    {
                        var new_item = dto.payments.First(c => c.payment_id == filter_id);
                        //级别的费率或结算费不能低于上级商户
                        if (oemer != null)
                        {
                            var payment = oemer_payments.FirstOrDefault(c => c.payment_id == new_item.payment_id);
                            if (payment != null)
                            {
                                foreach (var settle in payment.settles)
                                {
                                    var grade_settle = new_item.settles.FirstOrDefault(c => c.settle_type == settle.settle_type);
                                    if (grade_settle != null)
                                    {
                                        if (grade_settle.fee < settle.fee)
                                            throw new ServerErrorException("级别的费率不能低于上级商户");
                                        if (grade_settle.settle < settle.settle)
                                            throw new ServerErrorException("级别的结算费不能低于上级商户");
                                    }
                                }
                            }
                        }
                        //正式要删除
                        //var p_pay = context.Payments.FirstOrDefault(c => c.Id == filter_id);
                        //var p_sets = p_pay.Settles.ToObject<List<settle_setting>>();
                        //var settles = new List<settle_setting>();
                        //foreach (var p_set in p_sets.Where(c => c.settle_type == "T0")) {
                        //	var settle = new_item.settles.FirstOrDefault(c => c.settle_type == p_set.settle_type);
                        //	settles.Add(new settle_setting { code = p_set.code, settle_type = settle.settle_type, fee = settle.fee, settle = settle.settle });
                        //}
                        //foreach (var p_set in p_sets.Where(c => c.settle_type == "T1")) {
                        //	var settle = new_item.settles.FirstOrDefault(c => c.settle_type == p_set.settle_type);
                        //	settles.Add(new settle_setting { code = p_set.code, settle_type = settle.settle_type, fee = settle.fee, settle = settle.settle });
                        //}
                        //var item = model.MerchantPayments.First(c => c.PaymentId == filter_id);
                        //item.Settles = settles.ToJson();
                        //context.Entry(item).State = EntityState.Modified;
                        //end
                        var item = merchantPayments.First(c => c.PaymentId == filter_id);
                        item.Settles = new_item.settles.ToJson();
                        context.Entry(item).State = EntityState.Modified;
                    });
                }
                else
                {
                    //如果原来有数据，删除
                    if (merchantPayments.Count > 0)
                        merchantPayments.DataForEach(item => { context.Entry(item).State = EntityState.Deleted; });
                }
                #endregion

                int re = 0;
                if (!unchanged_Parent)
                {
                    re = context.Database.ExecuteSqlCommand("exec sp_member_update_path @p0,@p1", model.Id, dto.parent_id);
                }
                int result = _iUnitOfWork.Commit("Merchant" + model.Id, "Merchant" + model.MerchantNo);
                trans.Commit();
                return result;
            }
            catch (Exception ex)
            {
                var log = IocHelper.Get<ILogHelper>("data_error");
                log.Error(ex.Message, ex);
                trans.Rollback();
                return 0;
            }
        }

        /// <summary>
        /// 修改token 推荐人
        /// </summary>
        /// <returns></returns>
        public int UpdateParent(long userId, string parentMobile, long sysUserId, string oem_no)
        {
            var trans = context.Database.BeginTransaction();
            try
            {
                var oemer = Get(oem_no);
                var model = context.Merchants.FirstOrDefault(s => s.Id == userId && s.OemId == oemer.id);
                if (model == null) throw new ServerErrorException("商户不存在");
                var parent = context.Merchants.FirstOrDefault(s => s.Mobile == parentMobile && s.OemId == oemer.id); ;
                if (parent == null)
                    throw new ServerErrorException("找不到上级");
                //判断是否有修改上级
                bool unchanged_Parent = parent.Id == model.ParentId;
                List<string> tags = new List<string>();
                int re = 0;
                if (!unchanged_Parent)
                {
                    re = context.Database.ExecuteSqlCommand("exec sp_member_update_path @p0,@p1", model.Id, parent.Id);
                }
                tags.Add("Merchant" + model.Id);
                int result = 0;
                //如果调整了上级，就更新主页上级字段
                if (!unchanged_Parent && re > 0)
                {
                    model.ParentId = parent.Id;
                    result = _iUnitOfWork.Commit(tags.ToArray());
                    trans.Commit();
                }
                //如果没有修改返回1
                if (unchanged_Parent)
                    result = 1;
                return result;
            }
            catch (Exception ex)
            {
                var log = IocHelper.Get<ILogHelper>("data_error");
                log.Error(ex.Message, ex);
                trans.Rollback();
                return 0;
            }
        }

        /// <summary>
        /// token 修改昵称
        /// </summary>
        /// <param name="nickName"></param>
        /// <param name="id"></param>
        /// <returns></returns>
        public bool SaveUserNickName(string nickName, long id, string oem_no)
        {
            var oemer = Get(oem_no);
            bool ishas = context.Merchants.Exist(s => s.OemId == oemer.id && s.Name == nickName);
            if (ishas) throw new ServerErrorException("昵称已存在");
            var model = context.Merchants.FindById(id);
            model.Name = nickName;
            int result = _iUnitOfWork.Commit("Merchant" + model.Id);
            return result > 0;
        }

        /// <summary>
        /// 修改token 用户
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        public bool UpdateUser(merchant_dto dto)
        {
            var trans = context.Database.BeginTransaction();
            try
            {
                var model = context.Merchants.FindById(dto.id);
                var opid = model.ParentId;
                //判断是否有修改上级
                bool unchanged_Parent = dto.parent_id == model.ParentId;
                dto.ToDtoObject(model);
                int re = 0;
                if (!unchanged_Parent)
                {
                    //不要改变原上级，让存储过程修改
                    model.ParentId = opid;
                    re = context.Database.ExecuteSqlCommand("exec sp_member_update_path @p0,@p1", model.Id, dto.parent_id);
                    if (re > 0) model.ParentId = dto.parent_id;
                }
                int result = _iUnitOfWork.Commit("Merchant" + model.Id);
                trans.Commit();
                return result >= 0;
            }
            catch (Exception ex)
            {
                trans.Rollback();
                var log = IocHelper.Get<ILogHelper>("data_error");
                log.Error(ex.Message, ex);
                return false;
            }
        }

        public int Delete(long id)
        {
            this.context.Merchants.Remove(id);
            return this.context.SaveChanges();
        }
        /// <summary>
        /// 发起实名认证
        /// </summary>
        /// <param name="userId"></param>
        /// <returns></returns>
        public async Task<VerifyResult> GetVerifyToken(long userId)
        {
            var merchant = Get(userId);
            string domain = "cloudauth.aliyuncs.com";
            string ticketId = Guid.NewGuid().ToString();
            var parameters = new Dictionary<string, string>()
                {
                    {"Action", "GetVerifyToken"},
                     {"RegionId", "cn-xiamen"},
                      {"Biz", "Token"},
                       {"TicketId", ticketId},
                };
            var request = new AliyunSignHelp(HttpMethod.Get, parameters);
            var url = request.GetUrl(domain);
            string result = string.Empty;
            VerifyResult data = new VerifyResult();
            try
            {
                using (var httpClient = new HttpClient())
                {
                    var response = await httpClient.GetAsync(url);
                    response.EnsureSuccessStatusCode();
                    result = await response.Content.ReadAsStringAsync();
                    data = result.ToObject<VerifyResult>();
                }
                if (data.Success)
                {
                    MerchantFaces face = new MerchantFaces();
                    face.MerchantId = userId;
                    face.TicketId = ticketId;
                    face.CreateTime = DateTime.Now.ToUnix();
                    context.MerchantFaces.Add(face);
                    _iUnitOfWork.Commit();
                }
            }
            catch (Exception ex)
            {
                var log = IocHelper.Get<ILogHelper>("data_error");
                log.Error(ex.Message, ex);
            }
            return data;
        }
        /// <summary>
        /// 实名认证状态 认证资料
        /// </summary>
        /// <param name="userId"></param>
        /// <returns></returns>
        public async Task<VerifyStatusResult> GetVerifyStatus(long userId)
        {
            var merchant = context.Merchants.FindById(userId);
            var merchantFace = context.MerchantFaces.OrderByDescending(s => s.Id).FirstOrDefault(s => s.MerchantId == userId);
            var order = context.Orders.OrderByDescending(s => s.Id).FirstOrDefault(s => s.BuyId == userId && s.OrderType == 7 && s.Status == OrderStatus.WaitDelivery);
            if (order != null)
            {
                order.Status = OrderStatus.Finish;
            }//字段当做使用状态
            VerifyStatusResult data = new VerifyStatusResult();
            if (merchantFace != null)
            {
                string domain = "cloudauth.aliyuncs.com";
                var parameters = new Dictionary<string, string>()
                    {
                    {"Action", "GetStatus"},
                     {"RegionId", "cn-xiamen"},
                      {"Biz", "Token"},
                       {"TicketId", merchantFace.TicketId},
                };
                var materials_parameters = new Dictionary<string, string>()
                    {
                    {"Action", "GetMaterials"},
                     {"RegionId", "cn-xiamen"},
                      {"Biz", "Token"},
                       {"TicketId", merchantFace.TicketId},
                };
                var request = new AliyunSignHelp(HttpMethod.Get, parameters);
                var url = request.GetUrl(domain);
                string result = string.Empty;//获取认证状态
                string materials_result = string.Empty;
                var log = IocHelper.Get<ILogHelper>("data_error");
                try
                {
                    using (var httpClient = new HttpClient())
                    {
                        var response = await httpClient.GetAsync(url);
                        response.EnsureSuccessStatusCode();
                        result = await response.Content.ReadAsStringAsync();
                        log.Info(merchant.Mobile + "--" + result);
                        data = result.ToObject<VerifyStatusResult>();
                    }
                    if (data.Success)
                    {

                        merchantFace.StatusCode = data.Data.StatusCode;
                        merchantFace.AuditConclusions = data.Data.AuditConclusions;
                        merchantFace.SimilarityScore = data.Data.SimilarityScore;
                        merchantFace.AuthorityComparisonScore = data.Data.AuthorityComparisonScore;
                    }
                }
                catch (Exception ex)
                {
                    log.Error(ex.Message, ex);
                }
                try
                {
                    MaterialsResult materials_data = new MaterialsResult();//获取认证结果
                    var m_request = new AliyunSignHelp(HttpMethod.Get, materials_parameters);
                    var m_url = m_request.GetUrl(domain);
                    using (var httpClient = new HttpClient())
                    {
                        var response = await httpClient.GetAsync(m_url);
                        response.EnsureSuccessStatusCode();
                        materials_result = await response.Content.ReadAsStringAsync();
                        log.Info(merchant.Mobile + "--" + materials_result);
                        materials_data = result.ToObject<MaterialsResult>();
                        log.Info(materials_data.Success + materials_data.Data.Name + materials_data.Data.IdentificationNumber);
                    }
                    if (materials_data.Success)
                    {
                        var m_data = materials_data.Data;
                        merchantFace.Name = m_data.Name;
                        merchantFace.IdentificationNumber = m_data.IdentificationNumber;
                        merchantFace.IdCardType = m_data.IdCardType;
                        merchantFace.IdCardStartDate = m_data.IdCardStartDate;
                        merchantFace.IdCardExpiry = m_data.IdCardExpiry;
                        merchantFace.Address = m_data.Address;
                        merchantFace.Sex = m_data.Sex;
                        merchantFace.IdCardFrontPic = m_data.IdCardFrontPic;
                        merchantFace.IdCardBackPic = m_data.IdCardBackPic;
                        merchantFace.FacePic = m_data.FacePic;
                        merchantFace.EthnicGroup = m_data.EthnicGroup;
                    }
                }
                catch (Exception ex)
                {

                    log.Error(ex.Message, ex);
                }
            }
            //if (merchant.FaceStatus != -1)
            //    _iUnitOfWork.Commit("Merchant" + userId);

            return data;
        }
        #region 支付相关
        private static readonly object obj_mer_reg_lock = new object();

        /// <summary>
        /// 商户向通道进件
        /// </summary>
        /// <returns>The channel register.</returns>
        public string MerchantChannelRegister(merchant_register_model dto)
        {
            lock (obj_mer_reg_lock)
            {
                var trans = context.Database.BeginTransaction();
                try
                {
                    bool is_fee = !string.IsNullOrEmpty(dto.settle);
                    settle_setting settle_set = null;
                    if (is_fee)
                    {
                        decimal settle_v = decimal.Parse(dto.settle);
                        if (settle_v != 0) settle_v = settle_v / 100M;
                        settle_set = new settle_setting { code = dto.pay_code, fee = dto.fee, settle = settle_v, settle_type = dto.settle_type };
                    }
                    var oemer = Get(dto.merchant_no);
                    //oem商的通道
                    var oemer_payments = GetPayments(oemer.id).Where(c => c.payment.channel == dto.pay_channel);
                    Merchant model = context.Merchants.FirstOrDefault(c => c.MerchantNo == dto.bind_no);
                    //如果是新用户，增加商户进件和卡进件
                    if (model == null)
                    {
                        model = new Merchant();
                        model.Mobile = dto.mobile;
                        model.Name = dto.account_name;
                        model.CreateTime = model.LoginTime = DateTime.Now.ToUnix();
                        model.OpenId = model.MerchantNo = dto.bind_no;
                        model.Setting = new merchant_setting().ToJson();
                        model.AuthStatus = AuthStatusEnum.None;
                        model.ParentId = 0;
                        model.Depth = 1;
                        model.OemId = oemer.id;
                        //增加商户
                        context.Merchants.Add(model);
                        int result = _iUnitOfWork.Commit();
                        //增加商户通道进件
                        var register = dto.ToDtoObject<MerchantRegister>();
                        register.IsPatch = dto.is_patch;
                        register.Cards = "[]";
                        register.IsSuccess = 1;
                        register.MerchantId = model.Id;
                        context.MerchantRegisters.Add(register);
                        //增加费率和结算费
                        if (is_fee)
                        {
                            var settles = new List<settle_setting> { settle_set };
                            oemer_payments.ForEach(payment =>
                            {
                                context.MerchantPayments.Add(new MerchantPayment { MerchantId = model.Id, PaymentId = payment.payment_id, Settles = settles.ToJson() });
                            });
                        }
                        //增加关系
                        context.MemberPaths.Add(new MemberPath { MemberId = model.Id, ParentId = model.Id });
                        //增加上下级关系
                        result = _iUnitOfWork.Commit();
                    }
                    //如果已经做过商户进件做改件或新增卡进件
                    else
                    {
                        MerchantRegister register = null;
                        //是信用卡的可以进件多次
                        if (dto.is_more)
                            register = context.MerchantRegisters.FirstOrDefault(c => c.MerchantId == model.Id && c.PayChannel == dto.pay_channel && c.SettleType == dto.settle_type && c.AccountNo == dto.account_no);
                        else
                            register = context.MerchantRegisters.FirstOrDefault(c => c.MerchantId == model.Id && c.PayChannel == dto.pay_channel && c.SettleType == dto.settle_type);
                        //以下几个通道只需要进件一次即可
                        if (dto.pay_channel == PayChannel.UNIPAY || dto.pay_channel == PayChannel.SCORE ||
                            dto.pay_channel == PayChannel.TopPay || dto.pay_channel == PayChannel.ScenePay ||
                            dto.pay_channel == PayChannel.shanglvPay || dto.pay_channel == PayChannel.BaiHuoPay ||
                            dto.pay_channel == PayChannel.Slscore)
                        {
                            register = context.MerchantRegisters.FirstOrDefault(c => (c.PayChannel == PayChannel.SCORE || c.PayChannel == PayChannel.ScenePay ||
                                                                                      c.PayChannel == PayChannel.shanglvPay || c.PayChannel == PayChannel.BaiHuoPay ||
                                                                                      c.PayChannel == PayChannel.TopPay || c.PayChannel == PayChannel.Slscore)
                                                                                   && c.SettleType == dto.settle_type && c.Mobile == dto.mobile);
                        }
                        //如果进件不存在，增加进件
                        if (register == null)
                        {
                            register = dto.ToDtoObject<MerchantRegister>();
                            register.MerchantId = model.Id;
                            register.IsPatch = dto.is_patch;
                            register.Cards = "[]";
                            register.IsSuccess = 1;
                            context.MerchantRegisters.Add(register);
                        }
                        else
                        {
                            dto.ToDtoObject(register);
                            register.IsSuccess = 1;
                        }
                        if (is_fee)
                        {
                            //商户的通道
                            var merchant_payments = context.MerchantPayments.Where(c => c.MerchantId == model.Id && c.Payment.Channel == dto.pay_channel).ToList();
                            //修改要注意费率和结算是一个集合，可能是T0或T1的不同，要调用各自修改
                            oemer_payments.DataForEach(payment =>
                            {
                                //商户通道存在时，只需要更新费率和结算
                                var merchant_payment = merchant_payments.FirstOrDefault(c => c.PaymentId == payment.payment_id);
                                if (merchant_payment != null)
                                {
                                    var o_settles = merchant_payment.Settles.ToObject<List<settle_setting>>();
                                    //存在费率和结算－更新,不存在增加
                                    var sett = o_settles.FirstOrDefault(c => c.settle_type == dto.settle_type && c.code == dto.pay_code);
                                    if (sett != null)
                                    {
                                        sett.fee = settle_set.fee;
                                        sett.settle = settle_set.settle;
                                    }
                                    else
                                        o_settles.Add(settle_set);
                                    merchant_payment.Settles = o_settles.ToJson();
                                }
                                else
                                {
                                    //oem有增加新的通道时，商户也增加
                                    var settles = new List<settle_setting> { settle_set };
                                    context.MerchantPayments.Add(new MerchantPayment { MerchantId = model.Id, PaymentId = payment.payment_id, Settles = settles.ToJson() });
                                }
                            });
                        }
                        int result = _iUnitOfWork.Commit("Merchant" + model.Id, "Merchant" + model.MerchantNo);
                    }
                    trans.Commit();
                }
                catch (Exception ex)
                {
                    trans.Rollback();
                    var log = IocHelper.Get<ILogHelper>("data_error");
                    log.Error(ex.Message, ex);
                }
                return dto.bind_no;
            }
        }

        public int DeleteMerchantRegister(long id)
        {
            var model = context.MerchantRegisters.Find(id);
            var tags = new List<string> { "Merchant" + model.Merchant.Id, "Merchant" + model.MerchantNo };
            context.MerchantRegisters.Remove(model);
            int result = _iUnitOfWork.Commit(tags.ToArray());
            return result;
        }

        public merchant_register_dto GetMerchantChannelRegister(long id)
        {
            var result = context.MerchantRegisters.Where(c => c.Id == id).FromCacheFirstOrDefault<MerchantRegister, merchant_register_dto>("Merchant");
            return result;
        }

        public merchant_register_dto GetMerchantChannelRegister(long merchant_id, PayChannel channel)
        {
            var result = context.MerchantRegisters.Where(c => c.MerchantId == merchant_id && c.PayChannel == channel).FromCacheFirstOrDefault<MerchantRegister, merchant_register_dto>("Merchant");
            return result;
        }

        public int MerchantChannelRegister(merchant_register_dto dto)
        {
            var model = context.MerchantRegisters.Find(dto.id);
            model = dto.ToDtoObject<MerchantRegister>(model);
            var tags = new List<string> { "Merchant" + model.Merchant.Id, "Merchant" + model.MerchantNo };
            int result = _iUnitOfWork.Commit(tags.ToArray());
            return result;
        }

        public string IsRegisterChannel(string mobile)
        {
            var model = context.MerchantRegisters.FirstOrDefault(c => (c.PayChannel == PayChannel.UNIPAY ||
                                                                       c.PayChannel == PayChannel.SCORE ||
                                                                       c.PayChannel == PayChannel.TopPay ||
                                                                       c.PayChannel == PayChannel.ScenePay ||
                                                                       c.PayChannel == PayChannel.BaiHuoPay ||
                                                                       c.PayChannel == PayChannel.shanglvPay ||
                                                                       c.PayChannel == PayChannel.Slscore) && c.Mobile == mobile);
            return (model == null ? "" : model.MerchantNo);
        }

        public MerchantRegister GetRegisterCode(string id_card, PayChannel channel)
        {
            var merchantRegister = context.MerchantRegisters.FirstOrDefault(c => c.IdCard == id_card && c.PayChannel == channel);
            return merchantRegister;
        }

        public merchant_register_dto GetRegister(string id_card, PayChannel channel)
        {
            merchant_register_dto register = null;
            var merchantRegister = context.MerchantRegisters.FirstOrDefault(c => c.IdCard == id_card && c.PayChannel == channel);
            if (merchantRegister != null) register = merchantRegister.ToDtoObject<merchant_register_dto>();
            return register;
        }

        /// <summary>
        /// 所有已进件通道
        /// </summary>
        /// <param name="merchant_id"></param>
        /// <returns></returns>
        public List<merchant_register_dto> GetRegisters(long merchant_id)
        {
            var result = context.MerchantRegisters.Where(c => c.MerchantId == merchant_id).FromCache<MerchantRegister, merchant_register_dto>("Merchant" + merchant_id);
            return result;
        }

        /// <summary>
        /// 所有已开通支付方式
        /// </summary>
        /// <param name="merchant_id"></param>
        /// <returns></returns>
        public List<merchant_payment_dto> GetPayments(long merchant_id)
        {
            var result = context.MerchantPayments.Where(c => c.MerchantId == merchant_id).FromCache<MerchantPayment, merchant_payment_dto>("Merchant" + merchant_id);
            return result;
        }

        public int SetMerchantRegister(string merchant_no)
        {
            int result = 0;
            var merchantRegister = context.MerchantRegisters.FirstOrDefault(c => c.MerchantNo == merchant_no);
            if (merchantRegister != null)
            {
                merchantRegister.IsSuccess = 1;
                result = _iUnitOfWork.Commit("MerchantRegisters");
            }
            return result;
        }

        /// <summary>
        /// 查询用户的下一级，不包括本身
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public IEnumerable<merchant_info> GetOneChild(long id)
        {
            return base.context.Merchants.Where(c => c.ParentId == id).FromCache<Merchant, merchant_info>();
        }
        public PagedResult<merchant_dto> GetOneChild(MerchantChildQuery query)
        {
            var filter = PredicateBuilder.True<Merchant>();
            filter = filter.And(s => s.ParentId == query.merchant_id);
            var result = context.Merchants.FromCachePaged<Merchant, merchant_dto>(query.page, query.size, filter, orderBy => orderBy.OrderByDescending(s => s.CreateTime));
            return result;
        }
        #endregion
    }
}
